谁能用外行的术语解释 JSONP 是什么?

谁能用外行的术语解释 JSONP 是什么?

问题描述:

我知道 JSONP 是带有填充的 JSON.

I know JSONP is JSON with padding.

我了解什么是 JSON,以及如何通过 jQuery.getJSON()使用它代码>.但是,我不明白介绍JSONP时callback的概念.

I understand what JSON is, and how to use it with jQuery.getJSON(). However, I do not understand the concept of the callback when introducing JSONP.

谁能向我解释一下这是如何工作的?

Can anyone explain to me how this works?

前言:

这个答案已经有六年多了.虽然JSONP的概念和应用没有改变(即答案的详细信息仍然有效),您应该尽可能使用 CORS(即您的服务器API 支持它,并且浏览器支持就足够了),因为 JSONP 具有固有的安全风险.

Preface:

This answer is over six years old. While the concepts and application of JSONP haven't changed (i.e. the details of the answer are still valid), you should look to use CORS where possible (i.e. your server or API supports it, and the browser support is adequate), as JSONP has inherent security risks.

JSONP(JSON with Padding)是一种常用的方法绕过 Web 浏览器中的跨域策略.(您不得向浏览器认为位于不同服务器上的网页发出 AJAX 请求.)

JSONP (JSON with Padding) is a method commonly used to bypass the cross-domain policies in web browsers. (You are not allowed to make AJAX requests to a web page perceived to be on a different server by the browser.)

JSON 和 JSONP 在客户端和服务器上的行为不同.JSONP 请求不会使用 XMLHTTPRequest 和相关的浏览器方法进行分派.而是创建一个 标记,其源设置为目标 URL.然后将此脚本标记添加到 DOM(通常在 元素内).

JSON and JSONP behave differently on the client and the server. JSONP requests are not dispatched using the XMLHTTPRequest and the associated browser methods. Instead a <script> tag is created, whose source is set to the target URL. This script tag is then added to the DOM (normally inside the <head> element).

var xhr = new XMLHttpRequest();

xhr.onreadystatechange = function () {
  if (xhr.readyState == 4 && xhr.status == 200) {
    // success
  };
};

xhr.open("GET", "somewhere.php", true);
xhr.send();

JSONP 请求:

var tag = document.createElement("script");
tag.src = 'somewhere_else.php?callback=foo';

document.getElementsByTagName("head")[0].appendChild(tag);

JSON 响应和 JSONP 响应之间的区别在于 JSONP 响应对象作为参数传递给回调函数.


The difference between a JSON response and a JSONP response is that the JSONP response object is passed as an argument to a callback function.

{ "bar": "baz" }

JSONP:

foo( { "bar": "baz" } );

这就是为什么您会看到包含 callback 参数的 JSONP 请求,以便服务器知道包装响应的函数名称.


This is why you see JSONP requests containing the callback parameter, so that the server knows the name of the function to wrap the response.

这个函数必须存在于全局范围标签被浏览器评估(一旦请求已完成).

This function must exist in the global scope at the time the <script> tag is evaluated by the browser (once the request has completed).

在处理 JSON 响应和 JSONP 响应之间需要注意的另一个区别是,JSON 响应中的任何解析错误都可以通过包装尝试评估 responseText 来捕获在 try/catch 语句中.由于 JSONP 响应的性质,响应中的解析错误将导致无法捕获的 JavaScript 解析错误.

Another difference to be aware of between the handling of a JSON response and a JSONP response is that any parse errors in a JSON response could be caught by wrapping the attempt to evaluate the responseText in a try/catch statement. Because of the nature of a JSONP response, parse errors in the response will cause an uncatchable JavaScript parse error.

两种格式都可以通过在发起请求之前设置超时并在响应处理程序中清除超时来实现超时错误.

Both formats can implement timeout errors by setting a timeout before initiating the request and clearing the timeout in the response handler.

使用 jQuery 发出 JSONP 请求的用处在于 jQuery 确实所有工作都在后台为您服务.

The usefulness of using jQuery to make JSONP requests, is that jQuery does all of the work for you in the background.

默认情况下,jQuery 要求您在 AJAX 请求的 URL 中包含 &callback=?.jQuery 将采用您指定的 success 函数,为其分配一个唯一名称,并将其发布到全局范围内.然后它会将 &callback=? 中的问号 ? 替换为它指定的名称.

By default jQuery requires you to include &callback=? in the URL of your AJAX request. jQuery will take the success function you specify, assign it a unique name, and publish it in the global scope. It will then replace the question mark ? in &callback=? with the name it has assigned.

以下假设一个响应对象 { "bar" : "baz" }

The following assumes a response object { "bar" : "baz" }

var xhr = new XMLHttpRequest();

xhr.onreadystatechange = function () {
  if (xhr.readyState == 4 && xhr.status == 200) {
    document.getElementById("output").innerHTML = eval('(' + this.responseText + ')').bar;
  };
};

xhr.open("GET", "somewhere.php", true);
xhr.send();

JSONP:

function foo(response) {
  document.getElementById("output").innerHTML = response.bar;
};

var tag = document.createElement("script");
tag.src = 'somewhere_else.php?callback=foo';

document.getElementsByTagName("head")[0].appendChild(tag);