借助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使用removeChild方法动态删除div元素
Aug 01 Javascript
jQuery动态创建html元素的常用方法汇总
Sep 05 Javascript
node.js中的fs.writeFile方法使用说明
Dec 14 Javascript
基于JQuery实现分隔条的功能
Jun 17 Javascript
BootStrap实现带关闭按钮功能
Feb 15 Javascript
HTML5+Canvas调用手机拍照功能实现图片上传(下)
Apr 21 Javascript
[js高手之路]从原型链开始图解继承到组合继承的产生详解
Aug 28 Javascript
超出JavaScript安全整数限制的数字计算BigInt详解
Jun 24 Javascript
Vue安装浏览器开发工具的步骤详解
May 12 Javascript
VUE+elementui组件在table-cell单元格中绘制微型echarts图
Apr 20 Javascript
在vue-cli3.0 中使用预处理器 (Sass/Less/Stylus) 配置全局变量操作
Aug 10 Javascript
react 路由Link配置详解
Nov 11 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
一个查看session内容的函数
2006/10/09 PHP
PHP网站提速三大“软”招
2006/10/09 PHP
php获得文件扩展名三法
2006/11/25 PHP
php检测文本的编码
2015/07/26 PHP
php-app开发接口加密详解
2018/04/18 PHP
laravel高级的Join语法详解以及使用Join多个条件
2019/10/16 PHP
各种常用浏览器getBoundingClientRect的解析
2009/05/21 Javascript
判断JS对象是否拥有某种属性的两种方式
2013/12/02 Javascript
用模版生成HTML的的框架jquery.tmpl使用详解
2015/01/07 Javascript
JavaScript通过元素索引号删除数组中对应元素的方法
2015/03/18 Javascript
基于js实现投票的实例代码
2015/08/04 Javascript
体验jQuery和AngularJS的不同点及AngularJS的迷人之处
2016/02/02 Javascript
jquery取消事件冒泡的三种方法(推荐)
2016/05/28 Javascript
JavaScript中校验银行卡号的实现代码
2016/12/19 Javascript
vue之nextTick全面解析
2017/05/17 Javascript
element-ui带输入建议的input框踩坑(输入建议空白以及会闪出上一次的输入建议问题)
2019/01/15 Javascript
详解django模板与vue.js冲突问题
2019/07/07 Javascript
微信小程序移动拖拽视图-movable-view实例详解
2019/08/17 Javascript
H5 js点击按钮复制文本到粘贴板
2020/11/19 Javascript
在Django中创建URLconf相关的通用视图的方法
2015/07/20 Python
Python复制文件操作实例详解
2015/11/10 Python
python实现获取Ip归属地等信息
2016/08/27 Python
numpy 进行数组拼接,分别在行和列上合并的实例
2018/05/08 Python
Python实现爬虫爬取NBA数据功能示例
2018/05/28 Python
Python语言检测模块langid和langdetect的使用实例
2019/02/19 Python
python可视化text()函数使用详解
2020/02/11 Python
Python GUI编程学习笔记之tkinter界面布局显示详解
2020/03/30 Python
Django数据库操作之save与update的使用
2020/04/01 Python
Django模板报TemplateDoesNotExist异常(亲测可行)
2020/12/18 Python
香蕉共和国加拿大官网:Banana Republic加拿大
2018/08/06 全球购物
大学校运会广播稿
2014/02/03 职场文书
《雨点儿》教学反思
2014/04/14 职场文书
就业导师推荐信范文
2015/03/27 职场文书
教师节联欢会主持词
2015/07/04 职场文书
师德师风培训感言
2015/08/03 职场文书
Python操作CSV格式文件的方法大全
2021/07/15 Python