我知道JSONP加填充物是JSON.

我了解什么是JSON,以及如何在jQuery.getJSON()中使用它.然而,在介绍JSONP时,我不理解callback的概念.

谁能给我解释一下这是怎么回事吗?

推荐答案

前言:

这个答案已经有六年多的历史了.而JSONP的概念和应用并没有改变


JSONP(JSON with Padding)是一种通常用于 绕过Web浏览器中的跨域策略.(不允许您向浏览器认为位于不同服务器上的网页发出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" } );

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

该功能must exist在全局范围at the time中,<script>标签由浏览器判断(一旦请求完成).


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

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


使用jQuery

使用jQuery发出JSONP请求的用处在于,jQuery在后台为您执行all of the work.

默认情况下,jQuery要求您在Ajax请求的URL中包含&callback=?.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);

Jquery相关问答推荐

如何在 ReactJS 中使用 JQuery

为什么要两次声明 jQuery?

如何在 Angular 中使用 jQuery?

如何签入用户已在 Google recaptcha 中选中复选框的 js?

在完成前一个请求之前中止新的 AJAX 请求

未捕获的类型错误:无法读取未定义的属性“toLowerCase”

jQuery:获取数据属性

$(window).width() 与媒体查询不同

调用 e.preventDefault() 后提交表单

Bootstrap 的工具提示在悬停时将表格单元格向右移动一点

jquery - 单击事件不适用于动态创建的按钮

如何查找数组中所有出现的元素的索引?

清除并刷新 jQuery Chosen 下拉列表

如何获取 jQuery 下拉值 onchange 事件

如何在使用 jQuery 单击特定链接时打开 bootstrap 导航选项卡的特定选项卡?

jQuery - 使用发布数据重定向

等效于 C# LINQ Select 的 Javascript

jquery beforeunload 关闭(不离开)页面时?

如何在 $ajax POST 中传递参数?

复选框值始终为“打开”