jQuery jsonp(转载)
来源:https://www.jianshu.com/p/1efe671832e0
其他文章:https://www.cnblogs.com/chiangchou/p/jsonp.html
jsonp本身是专为跨域而诞生的。早期开发者面对跨域没什么好办法,突然有人想到,既然引入js文件是不受跨域限制的,可以随意跨域引入,那么,动态引入一个带有你想要的数据的js文件,不就实现了跨域了么?由此jsonp技术诞生。
注意,jsonp技术跟ajax没有任何关系,只不过jQuery带了一个坏的头,让人们误以为jsonp跟ajax有关。
原理
jsonp的原理简单说就是:
第一步,你的HTML中应当提前准备一个函数,比如叫ooo,大致如下,它只干一个事情,就是把json字符串转换为json对象:
function ooo(data) {
return JSON.parse(data);
}
第二步,你在你的HTML中用js拼接字符串的方式拼接一个类似于<script src="http://外域.com/xxx.php?callback=ooo"></script>
的script元素。这个http://外域.com/xxx.php?callback=ooo
的内容如下:
ooo({"name": "张学友"})
然后你需要操作DOM,把上面的<script src="http://外域.com/xxx.php?callback=ooo"></script>
插入到DOM中,这样浏览器就会把这个地址当做js文件载入,然后试图执行里面的js内容。
既然这个文件被当做js来插入DOM,那么里面所有代码都是js代码,这个ooo({"name": "张学友"})
就是js代码,浏览器会找有没有一个叫ooo的函数,显然有,我们刚才不是定义了一个ooo函数么?所以浏览器找到了这个函数,之后就执行这函数。
最后,我们就得到了一个json对象,而这个对象就是来自于外域服务器。由此,跨域达成。
没错吧,从头到尾并没有ajax什么事。
可以看出,本域跟外域沟通的桥梁,是外域的一个php文件,接头暗号就是路径里的参数callback=ooo
。也就是说,php文件要做的事情应该是:
获取callback参数的值,然后拼接一个字符串ooo({"name": "张学友"})
,其中ooo来自callback参数的值,{"name": "张学友"}是从sql中查询到的结果。
用jQuery实现jsonp的好处
然后说说jQuery的实现。jq为了让使用者更省心,当然是做了很多自动化的工作,下面都可以一一看到。主要是:
1、你不用自己写类似这样的函数,因为jQuery已经帮你写了:
function ooo(data) {
return JSON.parse(data);
}
2、你不用思考函数名用啥名,因为jQ会帮你瞎编一个函数名,通常长相是jQuery32108394227022163139_1498134481374
一大串。
jQuery中怎么实现jsonp
通常三种办法:
第一种,$.ajax()方法
当引入http://外域.com/xxx.php?callback=ooo
,php端必须让这个地址能打印出ooo({"name": "张学友"})
这样的内容,函数名ooo必须跟下面的jsonpCallback的值一致。json内容可以任意。
JS:
$.ajax({
url:'http://外域.com/xxx.php',
dataType:"jsonp",
jsonp: "callback",
jsonpCallback:"ooo",
success:function(data){
console.log(data);
}
});
这个例子里面,明确指定了jsonp: "callback"以及jsonpCallback:"ooo"。我们分别说一下:
jsonp: "callback"
是设置路径里的参数名。你这里写callback,那么jQuery发送请求的时候路径里就用callback=
jsonpCallback:"ooo"
是设置函数名。你这里写ooo,那么php必须返回ooo为函数名的内容。
这两者都可以省略,jsonp的值省略的话,缺省是callback。jsonpCallback的值省略的话,缺省是类似jsonp3731491014413739这样的'jsonp'加16位随机数。两者都省略的话,jQuery就会在路径后面接一个callback=jsonp3731491014413739这样的参数,那么,你的php就必须返回jsonp3731491014413739({"name": "张学友"})
这样的字符串。说白了,你如果js端想少写几个字,打算省掉这两个参数,那么php端就多写一些代码,需要先获取$_GET['callback']
的值,根据值拼接字符串,因此你就不可能写死函数名。
最佳实践是省掉这两个参数,不过你的php端就要对参数值做安全措施。
第二种,$.get()方法(作者推荐)
$.get()方法的基本用法是同域名抓数据,是真正的ajax原理。而高级用法就是抓jsonp数据。写法是:
$.get('http://外域.com/xxx.php', {各种数据}, function(data) {
console.log(data);
}, 'jsonp');
没有指定末尾的'jsonp'参数的时候,jQuery认为你想同域抓数据,会用xhr方法请求;只有加了参数,才认为你想抓jsonp数据。这一切由jQuery自动判断。
这个写法其实就是上面ajax写法的简化版,而且肯定设不了jsonp和jsonpCallback,所以你的php必须用类似echo $_GET['callback'].'({"name":"张学友"})';
这样的写法。假如你的路径中本来就有callback参数,而且这个callback是干别的用的,那么你就没法用$.get()方法。因为你真正的请求路径会是:http://外域/xxx.php?callback=12345678&callback=jQuery321040155744415047234_1498133674752&_=1498133674753
,看到了吧,两个callback参数,php只会认后一个,忽略前一个。
第三种:$.getJSON()方法
$.getJSON()方法跟$.get()方法类似,区别在于:
1、$.getJSON()的最后一个参数不用写,而$.get()方法的最后一个参数必须是'jsonp'。
2、$.getJSON()虽然省掉了最后一个参数,但这时候,你需要在路径中带上callback=?
或者abc=?
这样的字眼,这样jQuery会自动判断,既然你带上了参数,而且参数值是问号,那么jQuery就认为你想搞jsonp勾当,如果你不加任何参数,或者参数值不是问号,那么jQuery就认为你不想搞jsonp勾当,那么这时候$.getJSON()方法就全等于$.get(...,..., 'json')方法。
同样的,你如果用callback=?
,那么你php里应该是echo $_GET['callback'].'({"a": "张学友"})';
,如果你用abc=?
,那么你php里得是echo $_GET['abc'].'({"a": "张学友"})';
。
$.getJSON('http://外域/xxx.php?abc=?', {各种数据}, function(data) {
console.log(data);
});
结论
要让我选最好用的一个,我选$.get()方法,因为$.get()方法的最后一个参数'jsonp'
能显式声明这个请求是jsonp请求,再一个,$.getJSON()方法的url要加上callback=?
这种字眼,显得繁琐。
$.ajax()方法不到必要时不要用,必须用的时候当然一定要用。
作者:microkof
链接:https://www.jianshu.com/p/1efe671832e0
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
2018-06-22 echarts tab 切换问题整理
2017-06-22 Thinkphp 全选、反选 批量删除
2017-06-22 Thinkphp 图片上传
2017-06-22 thinkphp 百度编辑器和layer简单用法
2017-06-22 thinkphp 分页Pages
2017-06-22 thinkphp 网址后台典型页面
2017-06-22 thinphp 缓存机制导致代码不跟新