借助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系列(11) 执行上下文(Execution Contexts)
Jan 15 Javascript
模拟用户点击弹出新页面不会被浏览器拦截
Apr 08 Javascript
Javascript递归打印Document层次关系实例分析
May 15 Javascript
移动端H5开发 Turn.js实现很棒的翻书效果
Jun 20 Javascript
JS中常用的正则表达式
Sep 29 Javascript
微信开发 JS-SDK 6.0.2 经常遇到问题总结
Dec 08 Javascript
将鼠标焦点定位到文本框最后(代码分享)
Jan 11 Javascript
jQuery实现级联下拉框实战(5)
Feb 08 Javascript
基于jQuery代码实现圆形菜单展开收缩效果
Feb 13 Javascript
判断颜色是否合法的正则表达式(详解)
May 03 Javascript
Angular 2.x学习教程之结构指令详解
May 25 Javascript
详解微信小程序scroll-view横向滚动的实践踩坑及隐藏其滚动条的实现
Mar 14 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
基于mysql的论坛(1)
2006/10/09 PHP
php设计模式 Factory(工厂模式)
2011/06/26 PHP
php数组函数序列 之shuffle()和array_rand() 随机函数使用介绍
2011/10/29 PHP
php解析xml提示Invalid byte 1 of 1-byte UTF-8 sequence错误的处理方法
2013/11/14 PHP
PHP中Fatal error session_start()错误解决步骤
2014/08/05 PHP
LaravelS通过Swoole加速Laravel/Lumen详解
2018/03/02 PHP
php实现微信发红包功能
2018/07/13 PHP
PHP实现微信提现(企业付款到零钱)
2019/08/01 PHP
laravel 解决paginate查询多个字段报错的问题
2019/10/22 PHP
基于PHP实现用户登录注册功能的详细教程
2020/08/04 PHP
如何快速的呈现我们的网页的技巧整理
2007/07/01 Javascript
javascript call方法使用说明
2010/01/11 Javascript
轻松创建nodejs服务器(5):事件处理程序
2014/12/18 NodeJs
javascript文本模板用法实例
2015/07/31 Javascript
详解微信小程序——自定义圆形进度条
2016/12/29 Javascript
vue指令做滚动加载和监听等
2019/05/26 Javascript
微信小程序实现侧边分类栏
2019/10/21 Javascript
jQuery Datatables 动态列+跨列合并实现代码
2020/01/30 jQuery
vue使用微信扫一扫功能的实现代码
2020/04/11 Javascript
vue+element使用动态加载路由方式实现三级菜单页面显示的操作
2020/08/04 Javascript
Vue过滤器,生命周期函数和vue-resource简单介绍
2021/01/12 Vue.js
详解Python中find()方法的使用
2015/05/18 Python
学习python之编写简单乘法口诀表实现代码
2016/02/27 Python
python 排序算法总结及实例详解
2016/09/28 Python
Python实现的插入排序算法原理与用法实例分析
2017/11/22 Python
python matlibplot绘制3D图形
2018/07/02 Python
django之跨表查询及添加记录的示例代码
2018/10/16 Python
新年快乐! python实现绚烂的烟花绽放效果
2019/01/30 Python
学python安装的软件总结
2019/10/12 Python
numpy ndarray 按条件筛选数组,关联筛选的例子
2019/11/26 Python
python 爬虫之selenium可视化爬虫的实现
2020/12/04 Python
华为俄罗斯官方网上商城:购买Huawei手机和平板
2017/04/21 全球购物
应届大学生自荐书
2014/06/17 职场文书
学习优秀共产党员先进事迹思想报告
2014/09/17 职场文书
2016大学生诚信考试承诺书
2016/03/25 职场文书
python数字类型和占位符详情
2022/03/13 Python