借助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 相关文章推荐
用js实现的检测浏览器和系统的函数
Apr 09 Javascript
Javascript在IE和FireFox中的不同表现简析
Dec 03 Javascript
文本框只能选择数据到文本框禁止手动输入
Nov 22 Javascript
jquery ajax传递中文参数乱码问题及解决方法说明
Feb 07 Javascript
通过js获取上传的图片信息(临时保存路径,名称,大小)然后通过ajax传递给后端的方法
Oct 01 Javascript
JavaScript+html5 canvas绘制的小人效果
Jan 27 Javascript
vue模板语法-插值详解
Mar 06 Javascript
VUE axios发送跨域请求需要注意的问题
Jul 06 Javascript
使用jQuery实现两个div中按钮互换位置的实例代码
Sep 21 jQuery
10行原生JS实现文字无缝滚动(超简单)
Jan 02 Javascript
小程序实现人脸识别功能(百度ai)
Dec 23 Javascript
如何测量vue应用运行时的性能
Jun 21 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
php新建文件自动编号的思路与实现
2011/06/27 PHP
详细对比php中类继承和接口继承
2018/10/11 PHP
js中复制行和删除行的操作实例
2013/06/25 Javascript
javascript中的parseInt和parseFloat区别
2013/07/12 Javascript
DOM节点深度克隆函数cloneNode()用法实例
2015/01/12 Javascript
《JavaScript函数式编程》读后感
2015/08/07 Javascript
iscroll.js的上拉下拉刷新时无法回弹的解决方法
2016/02/18 Javascript
Angular.js中$apply()和$digest()的深入理解
2016/10/13 Javascript
自己封装的一个原生JS拖动方法(推荐)
2016/11/22 Javascript
通过Ajax使用FormData对象无刷新上传文件方法
2016/12/08 Javascript
Bootstrap警告(Alerts)的实现方法
2017/03/22 Javascript
AngularJs+Bootstrap实现漂亮的计算器
2017/08/10 Javascript
nodejs多版本管理总结
2018/04/03 NodeJs
基于Vue的延迟加载插件vue-view-lazy
2018/05/21 Javascript
vue移动端轻量级的轮播组件实现代码
2018/07/12 Javascript
boostrap模态框二次弹出清空原有内容的方法
2018/08/10 Javascript
mpvue开发音频类小程序踩坑和建议详解
2019/03/12 Javascript
Vue+Koa2 打包后进行线上部署的教程详解
2019/07/31 Javascript
通过实例了解JS 连续赋值
2019/09/24 Javascript
js实现小星星游戏
2020/03/23 Javascript
在Angular中实现一个级联效果的下拉框的示例代码
2020/05/20 Javascript
vue 使用post/get 下载导出文件操作
2020/08/07 Javascript
[01:24:34]2014 DOTA2华西杯精英邀请赛5 24 DK VS LGD
2014/05/25 DOTA
Python3使用requests发闪存的方法
2016/05/11 Python
Django内容增加富文本功能的实例
2017/10/17 Python
解决python中遇到字典里key值为None的情况,取不出来的问题
2018/10/17 Python
python实现图片中文字分割效果
2019/07/22 Python
使用wxpy实现自动发送微信消息功能
2020/02/28 Python
使用Pycharm在运行过程中,查看每个变量的操作(show variables)
2020/06/08 Python
美国宠物美容和宠物用品购物网站:Cherrybrook
2018/12/07 全球购物
食堂个人先进事迹
2014/01/22 职场文书
社区戒毒工作方案
2014/06/04 职场文书
党在我心中的演讲稿
2014/09/13 职场文书
2014幼儿园教师个人工作总结
2014/11/08 职场文书
西游降魔篇观后感
2015/06/15 职场文书
2015年教师节新闻稿
2015/07/17 职场文书