什么是 JSONP,为什么要创建它?

2022-01-31 00:00:00 json terminology javascript jsonp

我了解 JSON,但不了解 JSONP.维基百科关于 JSON 的文档 是 JSONP 的最高搜索结果.它是这样说的:

I understand JSON, but not JSONP. Wikipedia's document on JSON is (was) the top search result for JSONP. It says this:

JSONP 或带填充的 JSON"是一种 JSON 扩展,其中将前缀指定为调用本身的输入参数.

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

嗯?什么电话?这对我来说没有任何意义.JSON 是一种数据格式.没有电话.

Huh? What call? That doesn't make any sense to me. JSON is a data format. There's no call.

第二个搜索结果来自一个叫 Remy,写这篇关于 JSONP 的文章:

The 2nd search result is from some guy named Remy, who writes this about JSONP:

JSONP 是脚本标签注入,将来自服务器的响应传递给用户指定的函数.

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

我可以理解,但它仍然没有任何意义.

I can sort of understand that, but it's still not making any sense.

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

So what is JSONP? Why was it created (what problem does it solve)? And why would I use it?

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

Addendum: I've just created a new page for JSONP on Wikipedia; it now has a clear and thorough description of JSONP, based on jvenema's answer.

推荐答案

其实并没有太复杂...

It's actually not too complicated...

假设您在域 example.com 上,并且想要向域 example.net.为此,您需要跨域边界,这是大多数浏览器领域中的no-no.

Say you're on domain example.com, and you want to make a request to domain example.net. To do so, you need to cross domain boundaries, a no-no in most of browserland.

绕过此限制的一项是 <script> 标签.当您使用脚本标签时,域限制会被忽略,但在正常情况下,您无法对结果真正做任何操作,脚本只会被评估.

The one item that bypasses this limitation is <script> tags. When you use a script tag, the domain limitation is ignored, but under normal circumstances, you can't really do anything with the results, the script just gets evaluated.

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

Enter JSONP. When you make your request to a server that is JSONP enabled, you pass a special parameter that tells the server a little bit about your page. That way, the server is able to nicely wrap up its response in a way that your page can handle.

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

For example, say the server expects a parameter called callback to enable its JSONP capabilities. Then your request would look like:

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

如果没有 JSONP,这可能会返回一些基本的 JavaScript 对象,如下所示:

Without JSONP, this might return some basic JavaScript object, like so:

{ foo: 'bar' }

但是,使用 JSONP,当服务器接收到回调"参数时,它会稍微不同地包装结果,返回如下内容:

However, with JSONP, when the server receives the "callback" parameter, it wraps up the result a little differently, returning something like this:

mycallback({ foo: 'bar' });

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

As you can see, it will now invoke the method you specified. So, in your page, you define the callback function:

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

现在,当脚本被加载时,它将被评估,并且你的函数将被执行.瞧,跨域请求!

And now, when the script is loaded, it'll be evaluated, and your function will be executed. Voila, cross-domain requests!

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

It's also worth noting the one major issue with JSONP: you lose a lot of control of the request. For example, there is no "nice" way to get proper failure codes back. As a result, you end up using timers to monitor the request, etc, which is always a bit suspect. The proposition for JSONRequest is a great solution to allowing cross domain scripting, maintaining security, and allowing proper control of the request.

如今(2015 年),CORS 是推荐的方法,而不是 JSONRequest.JSONP 对于旧版浏览器支持仍然有用,但考虑到安全隐患,除非您别无选择,否则 CORS 是更好的选择.

These days (2015), CORS is the recommended approach vs. JSONRequest. JSONP is still useful for older browser support, but given the security implications, unless you have no choice CORS is the better choice.

相关文章