借助script进行Http跨域请求:JSONP实现原理及代码


Posted in Javascript onMarch 19, 2013

<script>元素的src属性能设置URL并发起HTTP GET请求, 使用<script>元素实现脚本操作HTTP可以跨域通信而不受限与同源策略. 通常, 使用基于<script>的Ajax传输协议时, 服务器响应采用JSON编码的数据格式, 当执行脚本时候, JavaScript解析器能够自动将其解码. 由于它使用JSON数据格式, 因此这种Ajax传输协议也叫做"JSONP". 所以使用jsonp技术, 只需要设置<script>的src属性, 并且插入到document中, 然后浏览器就会发送一个http请求以下载src属性所执行的url.

当使用<script>元素调用数据时, 响应内容必须用JavaScript函数名和圆括号包裹起来(也就是只能作为函数的参数), 而不是直接的一段json数据:

response( 
[1, 2, {"hello", "world"}] 
)

为了可行期间, 我们必须通过某种方式告诉服务, 它正在从一个<script>元素调用, 必须返回一个jsonp响应, 而不是普通的json, 这个可以通过在url中添加一个查询参数来实现: 例如, 追加"?json"(或者&json)

在实践中, 支持jsonp的服务不会强制指定客户端必须实现的回调函数名称, 比如response. 相反它们使用查询参数的值, 允许客户端指定一个函数名,然后使用函数名去填充响应.

//根据指定的url发送一个json请求 
//然后把解析得到的响应数据传递给回调函数 
//在url中添加一个名为jsonp的查询参数, 用于指定该请求的回调函数的名称 
function getJSONP(url, callback){ 
//为本次请求创建一个唯一的回调函数名称 
var cbnum = "cb"+getJSONP.counter++; 
var cbname = "getJSONP."+cbnum; //作为jsonp函数的属性 
//将回调函数名称以表单编码的形式添加到url查询部分中 
if(url.indexOf("?") === -1){ 
url += "?jsonp="+cbname; 
}else{ 
url += "&jsonp="+cbname; 
} 
//创建<script>用于发送请求 
var script = document.createElement("script"); 
//定义被脚本执行的回调函数 
getJSONP[cbnum] = function(response){ 
try{ 
callback(response); //处理响应 
} 
finally{ 
//删除该函数, 并移除相应script元素 
delete getJSONP[cbnum]; 
script.parentNode.removeChild(script); 
} 
} 
//立即触发http请求 
script.src = url; 
document.body.appendChild(script); 
} 
getJSONP.counter = 0;
Javascript 相关文章推荐
javascript 闭包疑问
Dec 30 Javascript
js为鼠标添加右击事件防止默认的右击菜单弹出
Jul 29 Javascript
IE10中flexigrid无法显示数据的解决方法
Jul 26 Javascript
javascript从作用域链谈闭包
Jul 29 Javascript
JavaScript深度复制(deep clone)的实现方法
Feb 19 Javascript
使用vue-router设置每个页面的title方法
Feb 11 Javascript
详解webpack import()动态加载模块踩坑
Jul 17 Javascript
Vue CLI 3搭建vue+vuex最全分析(推荐)
Sep 27 Javascript
JavaScript实现简单随机点名器
Nov 21 Javascript
vue移动端使用canvas签名的实现
Jan 15 Javascript
vue中使用router全局守卫实现页面拦截的示例
Oct 23 Javascript
解决vuex改变了state的值,但是页面没有更新的问题
Nov 12 Javascript
DIV+CSS+JS不间断横向滚动实现代码
Mar 19 #Javascript
下载文件个别浏览器文件名乱码解决办法
Mar 19 #Javascript
jQuery点击tr实现checkbox选中的方法
Mar 19 #Javascript
js多级树形弹出一个小窗口层(非常好用)实例代码
Mar 19 #Javascript
Javascript中valueOf与toString区别浅析
Mar 19 #Javascript
Javascript Throttle &amp; Debounce应用介绍
Mar 19 #Javascript
JS 实现获取打开一个界面中输入的值
Mar 19 #Javascript
You might like
无线电的诞生过程
2021/03/01 无线电
PHP中break及continue两个流程控制指令区别分析
2011/04/18 PHP
解析如何去掉CodeIgniter URL中的index.php
2013/06/25 PHP
php Calender(日历)代码分享
2014/01/03 PHP
php中error与exception的区别及应用
2014/07/28 PHP
document.designMode的功能与使用方法介绍
2007/11/22 Javascript
创建一个复制UBB软件信息的链接或按钮的js代码
2008/01/06 Javascript
js实现每日自动换一张图片的方法
2015/05/04 Javascript
jQuery满屏焦点图左右滚动特效代码分享
2015/09/07 Javascript
jQuery实现选项联动轮播效果【附实例】
2016/04/19 Javascript
jQuery使用Layer弹出层插件闪退问题
2016/12/22 Javascript
基于jQuery选择器之表单对象属性筛选选择器的实例
2017/09/19 jQuery
基于JavaScript表单脚本(详解)
2017/10/18 Javascript
jquery-file-upload 文件上传带进度条效果
2017/11/21 jQuery
node+koa2+mysql+bootstrap搭建一个前端论坛
2018/05/06 Javascript
Javascript模拟实现new原理解析
2020/03/03 Javascript
javascript实现移动端上传图片功能
2020/08/18 Javascript
python如何实现excel数据添加到mongodb
2015/07/30 Python
Python实现二叉堆
2016/02/03 Python
Python 专题六 局部变量、全局变量global、导入模块变量
2017/03/20 Python
Django视图之ORM数据库查询操作API的实例
2017/10/27 Python
Python编程实现使用线性回归预测数据
2017/12/07 Python
Python自动发送邮件的方法实例总结
2018/12/08 Python
django之静态文件 django 2.0 在网页中显示图片的例子
2019/07/28 Python
django 解决扩展自带User表遇到的问题
2020/05/14 Python
Numpy(Pandas)删除全为零的列的方法
2020/09/11 Python
莫斯科制造商的廉价皮大衣:Fursk
2020/06/09 全球购物
广州某公司软件工程师面试题
2014/12/22 面试题
会计与审计毕业生自荐信范文
2013/12/30 职场文书
优秀的茶餐厅创业计划书
2014/01/03 职场文书
2014年销售工作总结
2014/12/01 职场文书
2014小学数学教师个人工作总结
2014/12/18 职场文书
英文升职感谢信
2015/01/23 职场文书
2015年高中生国庆节演讲稿
2015/07/30 职场文书
企业转让协议书(范文2篇)
2019/08/15 职场文书
python3实现Dijkstra算法最短路径的实现
2021/05/12 Python