小编典典

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

all

我知道JSONPJSON填充。

我了解 JSON
是什么,以及如何将它与jQuery.getJSON().
callback但是,在介绍 JSONP 时,我不明白 的概念。

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


阅读 91

收藏
2022-03-21

共1个答案

小编典典

前言:

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


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

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

JSON请求:

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 响应对象作为参数传递给回调函数。

JSON:

{ "bar": "baz" }

JSONP:

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

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

在浏览器评估标签 (一旦请求完成),此函数 必须存在 于全局范围内。 __<script>


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

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


使用 jQuery

使用jQuery发出 JSONP 请求的用处在于 jQuery在后台为您完成
所有工作。

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


可比较的 JSON/JSONP 实现

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

JSON:

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);
2022-03-21