关于javascript:什么是JSONP,为什么要创建它?

What is JSONP, and why was it created?

我了解JSON,但不了解JSONP。维基百科关于JSON的文档是JSONP的最热门搜索结果。它说:

JSONP or"JSON with padding" is a JSON extension wherein a prefix is specified as an input argument of the call itself.

呵呵?叫什么?这对我来说毫无意义。JSON是一种数据格式。没有电话。

第二个搜索结果来自一个叫Remy的人,他写了关于jsonp的文章:

JSONP is script tag injection, passing the response from the server in to a user specified function.

我可以理解,但这仍然没有任何意义。

那么什么是jsonp?为什么要创建它(它解决了什么问题)?我为什么要用它?

附录:我刚刚在维基百科上为jsonp创建了一个新页面;现在它根据jvenema的答案对jsonp进行了清晰而全面的描述。


其实并不太复杂…

假设你在域example.com上,你想向域example.net发出请求。要做到这一点,你需要跨越领域边界,在大多数浏览器领域都是不允许的。

绕过这个限制的一个项目是标签。当您使用脚本标记时,域限制被忽略,但是在正常情况下,您不能对结果做任何实际操作,脚本只会得到评估。

输入JSONP。当您向启用了JSONP的服务器发出请求时,您将传递一个特殊的参数,该参数告诉服务器一些关于您的页面的信息。这样,服务器就能够以页面可以处理的方式很好地总结其响应。

例如,假设服务器需要一个名为"callback"的参数来启用其JSONP功能。那么您的请求如下:

1
http://www.example.net/sample.aspx?callback=mycallback

如果没有jsonp,这可能会返回一些基本的javascript对象,如:

1
{ foo: 'bar' }

但是,对于jsonp,当服务器接收到"callback"参数时,它对结果进行了稍微不同的包装,返回如下内容:

1
mycallback({ foo: 'bar' });

如您所见,它现在将调用您指定的方法。因此,在您的页面中,您定义回调函数:

1
2
3
mycallback = function(data){
  alert(data.foo);
};

现在,当加载脚本时,将对其进行评估,并执行函数。瞧,跨域请求!

同样值得注意的是,JSONP的一个主要问题是:您失去了对请求的大量控制。例如,没有"好"的方法来获取正确的故障代码。结果,您最终使用计时器来监视请求等,这总是有点可疑。JSONREQUEST的提议是一个很好的解决方案,它允许跨域脚本、维护安全性,并允许对请求进行适当的控制。

这些天(2015年),CORS是推荐的方法,而不是JSONREQUEST。JSONP对于旧的浏览器支持仍然有用,但是考虑到安全性的影响,除非您没有选择,否则CORS是更好的选择。