首页 >web前端 >js教程 >JQuery的JSONP用示例解释了

JQuery的JSONP用示例解释了

William Shakespeare
William Shakespeare原创
2025-02-17 10:34:10166浏览

jQuery's JSONP Explained with Examples

要点总结

  • JSONP(带填充的 JSON)允许跨域 Ajax 调用,从而规避了限制脚本访问不同来源数据的同源策略。这是通过让服务器返回包含函数调用的 JSON 数据来实现的,浏览器可以解释该函数调用。
  • 虽然 JSONP 对于从不同来源获取数据和访问各种服务的内容很有价值,但它也有一些局限性。JSONP 只能执行跨域 GET 请求,并且必须由服务器显式支持。它还存在潜在的安全问题,因为它为跨站点脚本 (XSS) 攻击打开了可能性。
  • 同源策略的其他解决方案包括使用代理或实现跨源资源共享 (CORS)。代理允许服务器端代码执行跨源请求,而 CORS 通过在响应中包含新的 Access-Control-Allow-Origin HTTP 标头来允许浏览器进行跨域通信。但是,每种方法都有其自身的缺点和局限性。

这篇文章于 2016 年 6 月 23 日进行了更新,以解决质量问题。旧文章的相关评论已被删除。如果您正在开发基于 Web 的应用程序,并且尝试从不受您控制的域加载数据,则您很可能在浏览器的控制台中看到以下消息:XMLHttpRequest cannot load https://www.php.cn/link/0df0dbfc4725c2259dc0bb045e9bf6d2. No ‘Access-Control-Allow-Origin’ header is present on the requested resource. Origin ‘https://www.php.cn/link/28db3b5e7bfadf38b792da7192530ac1’ is therefore not allowed access.

在本文中,我们将探讨导致此错误的原因,以及如何通过使用 jQuery 和 JSONP 来进行跨域 Ajax 调用来解决此问题。

同源策略

常规网页可以使用 XMLHttpRequest 对象向远程服务器发送和接收数据,但是同源策略限制了它们可以执行的操作。这是浏览器安全模型中的一个重要概念,它规定网页浏览器可能只允许页面 A 上的脚本访问页面 B 上的数据,如果这两个页面具有相同的来源。页面的来源由其协议主机端口号定义。例如,此页面的来源是“https”、“www.sitepoint.com”、“80”。同源策略是一种安全机制。它可以防止脚本从您的域读取数据并将其发送到它们的服务器。如果没有这个,恶意网站很容易将您的会话信息抓取到另一个站点(例如 Gmail 或 Twitter),并代表您执行操作。不幸的是,它还会导致我们上面看到的错误,并且经常会给试图完成合法任务的开发人员带来麻烦。

失败的示例

让我们看看什么不起作用。这是一个位于不同域上的 JSON 文件,我们希望使用 jQuery 的 getJSON 方法加载它。

<code class="language-javascript">$.getJSON(
  "http://run.plnkr.co/plunks/v8xyYN64V4nqCshgjKms/data-1.json",
  function(json) { console.log(json); }
);</code>

如果您在浏览器中打开控制台尝试一下,您将看到类似于上面提到的消息。那么我们能做什么呢?

可能的解决方法

幸运的是,并非所有内容都受同源策略的影响。例如,完全可以将图像或脚本从不同域加载到您的页面中——当您从 CDN 包含 jQuery(例如)时,您正在执行此操作。这意味着我们可以创建一个 <script></script> 标签,将其 src 属性设置为我们的 JSON 文件,并将其注入页面。

<code class="language-javascript">var script = $("<script>", {
    src: "http://run.plnkr.co/plunks/v8xyYN64V4nqCshgjKms/data-1.json",
    type: "application/json"
  }
);

$("head").append(script);</script></code>

虽然这有效,但对我们帮助不大,因为我们无法访问它包含的数据。

JSONP 入门

JSONP(代表带填充的 JSON)基于此技术,并为我们提供了一种访问返回数据的方法。它是通过让服务器返回包含函数调用(“填充”)的 JSON 数据来实现的,然后浏览器可以解释该函数调用。此函数必须在评估 JSONP 响应的页面中定义。

让我们看看之前的示例是什么样的。这是一个更新的 JSON 文件,它将原始 JSON 数据包装在一个 jsonCallback 函数中。

<code class="language-javascript">function jsonCallback(json){
  console.log(json);
}

$.ajax({
  url: "http://run.plnkr.co/plunks/v8xyYN64V4nqCshgjKms/data-2.json",
  dataType: "jsonp"
});</code>

这会将预期结果记录到控制台中。我们现在有了(尽管相当有限)跨域 Ajax。

第三方 API

一些第三方 API 允许您指定回调函数的名称,当请求返回时应执行该函数。一个这样的 API 是 GitHub API。

在下面的示例中,我们获取 John Resig(jQuery 创建者)的用户信息,并使用 logResults 回调函数将响应记录到控制台中。

<code class="language-javascript">function logResults(json){
  console.log(json);
}

$.ajax({
  url: "https://api.github.com/users/jeresig",
  dataType: "jsonp",
  jsonpCallback: "logResults"
});</code>

这也可以写成:

<code class="language-javascript">$.getJSON("https://api.github.com/users/jeresig?callback=?",function(json){
  console.log(json);
});</code>

URL 末尾的 ? 告诉 jQuery 它正在处理 JSONP 请求而不是 JSON。然后,jQuery 自动注册回调函数,当请求返回时它会调用该函数。

如果您想了解更多关于 jQuery 的 getJSON 方法的信息,请查看:Ajax/jQuery.getJSON 简单示例

注意事项

但正如您现在可能已经意识到的那样,这种方法有一些缺点。

例如,JSONP 只能执行跨域 GET 请求,并且服务器必须显式支持它。JSONP 也并非没有安全问题,因此让我们简要介绍一些其他解决方案。

使用代理

服务器端代码不受同源策略的约束,可以毫无问题地执行跨源请求。因此,您可以创建某种代理并使用它来检索您需要的任何数据。参考我们的第一个示例:

<code class="language-php">/* proxy.php */
$url = "http://run.plnkr.co/plunks/v8xyYN64V4nqCshgjKms/data-1.json";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec ($ch);
curl_close ($ch);
echo $result;</code>

在客户端:

<code class="language-javascript">$.getJSON("https://www.php.cn/link/28db3b5e7bfadf38b792da7192530ac1.com/proxy.php", function(json) {
  console.log(json);
})</code>

但这方法也有缺点。例如,如果第三方站点使用 cookie 进行身份验证,则此方法将不起作用。

CORS

跨源资源共享 (CORS) 是一个 W3C 规范,允许浏览器进行跨域通信。这是通过在响应中包含新的 Access-Control-Allow-Origin HTTP 标头来实现的。

参考我们的第一个示例,您可以将以下内容添加到 .htaccess 文件(假设为 Apache)以允许来自不同来源的请求:

<code class="language-javascript">$.getJSON(
  "http://run.plnkr.co/plunks/v8xyYN64V4nqCshgjKms/data-1.json",
  function(json) { console.log(json); }
);</code>

(如果您运行的服务器不是 Apache,请查看此处:https://www.php.cn/link/819e2e55be8ef0957b56ea94356bfb79

您可以在我们最近的教程之一中了解更多关于 CORS 的信息:深入了解 CORS

结论

JSONP 允许您绕过同源策略,并在某种程度上进行跨域 Ajax 调用。它不是灵丹妙药,当然也有其问题,但在某些情况下,当从不同来源获取数据时,它可以证明是无价的。

JSONP 还使您可以从不同的服务中提取各种内容。许多著名的网站提供 JSONP 服务(例如 Flickr),允许您通过预定义的 API 访问它们的内容。您可以在 ProgrammableWeb API 目录中找到它们的完整列表。

(以下为FAQ部分,已根据原文进行调整和简化,避免重复信息)

关于 JSONP 的常见问题解答 (FAQ)

  • JSON 和 JSONP 的主要区别是什么? JSON 和 JSONP 都是用于处理服务器和 Web 应用程序之间数据的格式。主要区别在于它们处理跨域请求的方式。JSON 由于同源策略(Web 浏览器中实施的安全措施)而无法支持跨域请求。另一方面,JSONP 通过使用填充方法来绕过此策略,允许从与客户端不同的域的服务器请求数据。

  • JSONP 如何绕过同源策略? JSONP 通过使用填充或“填充请求”方法来绕过同源策略。在此方法中,客户端通过将回调函数附加到 URL 来请求不同域的服务器的数据。然后,服务器将请求的数据包装在此函数中并将其发送回客户端。客户端执行此函数,从而访问数据。此方法允许 JSONP 克服同源策略施加的跨域限制。

  • JSONP 安全吗? 虽然 JSONP 为同源策略提供了一种解决方法,但它确实存在自身的安全风险。由于 JSONP 涉及执行从服务器接收的脚本,因此如果服务器遭到破坏,它会为跨站点脚本 (XSS) 攻击打开可能性。因此,务必仅与受信任的来源一起使用 JSONP。

  • JSONP 可以处理错误响应吗? 与 JSON 不同,JSONP 没有内置的错误处理。如果 JSONP 请求失败,浏览器不会引发错误,并且不会执行回调函数。要处理 JSONP 中的错误,您可以实现超时机制,如果在指定时间内未执行回调函数,则会触发错误。

  • 如何使用 jQuery 发出 JSONP 请求? jQuery 提供了一种简单的方法,可以使用 $.ajax() 方法发出 JSONP 请求。您需要在 $.ajax() 设置中将 dataType 指定为“jsonp”。

  • JSONP 的局限性是什么? JSONP 有一些限制。它只支持 GET 请求,不支持 POST 或其他 HTTP 方法。它还缺乏错误处理功能。此外,由于其绕过同源策略的方法,JSONP 会带来安全风险。

  • JSONP 现在还使用吗? 虽然 JSONP 过去是进行跨域请求的流行解决方案,但如今由于 CORS(跨源资源共享)的出现,其使用频率较低,CORS 提供了一种更安全、更强大的进行跨域请求的方法。

以上是JQuery的JSONP用示例解释了的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn