(10个答案)
三年前关闭的
我知道JSONP是带填充的JSON
我了解什么是JSON,以及如何将它与jQuery.getJSON()一起使用。然而,在介绍JSONP时,我不理解回调的概念
有人能给我解释一下这是怎么回事吗
前言:
这个答案已经有六年多的历史了。而JSONP的概念和应用并没有改变
(即答案的细节仍然有效),您应该
尽可能使用CORS
(即您的服务器或
API支持它,并且
浏览器支持已足够),
因为JSONP具有固有的安全风险
JSONP(JSON with Padding)是一种常用于
绕过web浏览器中的跨域策略。(不允许对浏览器认为位于不同服务器上的网页发出AJAX请求。)
JSON和JSONP在客户端和服务器上的行为不同。JSONP请求不会使用XMLHTTPRequest和相关的浏览器方法进行调度。而是一个<;脚本>标记,其源设置为目标URL。然后将此脚本标记添加到DOM中(通常在<;head>;元素中)
JSON请求:
var xhr=new XMLHttpRequest();
xhr.onreadystatechange=函数(){
如果(xhr.readyState==4&;xhr.status==200){
//成功
};
};
open(“GET”,“somewhere.php”,true);
xhr.send();
JSONP请求:
var tag=document.createElement(“脚本”);
tag.src=https://stackoverflow.com/questions/3839966/somewhere_else.php?callback=foo';
document.getElementsByTagName(“head”)[0].appendChild(标记);
JSON响应和JSONP响应之间的区别在于JSONP响应对象作为参数传递给回调函数
JSON:
{“bar”:“baz”}
JSONP:
foo({“bar”:“baz”});
这就是为什么会看到JSONP请求包含callback参数,以便服务器知道包装响应的函数名
此函数必须在时存在于全局范围中;脚本>标记由浏览器评估(一旦请求完成)
处理JSON响应和JSONP响应之间需要注意的另一个区别是,JSON响应中的任何解析错误都可以通过包装对responseText求值的尝试来捕获
在try/catch语句中。由于JSONP响应的性质,响应中的解析错误将导致不可修补的JavaScript解析错误
这两种格式都可以通过在启动请求之前设置超时并在响应处理程序中清除超时来实现超时错误
使用jQuery
使用jQuery发出JSONP请求的好处在于,jQuery在后台为您完成所有工作
默认情况下,jQuery要求您包括&;回调=?在AJAX请求的URL中。jQuery将接受您指定的success函数,为它指定一个唯一的名称,并在全局范围内发布它。然后,它将替换中的问号及其分配的名称?&;callback=?
可比较的JSON/JSONP实现
下面假设一个响应对象{“bar”:“baz”}
JSON:
var xhr=new XMLHttpRequest();
xhr.onreadystatechange=函数(){
如果(xhr.readyState==4&;xhr.status==200){
document.getElementById(“output”).innerHTML=eval(“(“+this.responseText+”))”).bar;
};
};
open(“GET”,“somewhere.php”,true);
xhr.send();
JSONP:
函数foo(响应){
document.getElementById(“输出”).innerHTML=response.bar;
};
var tag=document.createElement(“脚本”);
tag.src=https://stackoverflow.com/questions/3839966/somewhere_else.php?callback=foo';
document.getElementsByTagName(“head”)[0].appendChild(标记);