谁能通俗地解释一下 JSONP 是什么?

发布于 2024-09-25 09:26:10 字数 263 浏览 0 评论 0原文

我知道 JSONP 是带有填充的 JSON

我了解 JSON 是什么,以及如何将其与 jQuery.getJSON()< 一起使用/a>.但是,我在引入JSONP时不理解callback的概念。

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

I know JSONP is JSON with padding.

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

把时间冻结 2024-10-02 09:26:11

前言:

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


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

JSON 和 JSONP 在客户端和服务器上的行为不同。 JSONP 请求不是使用 XMLHTTPRequest 和关联的浏览器方法分派的。相反,会创建一个

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 请求,以便服务器知道包装响应的函数名称。

在浏览器评估


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

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


使用 jQuery

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

默认情况下,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);

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) 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 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).

JSON Request:

var xhr = new XMLHttpRequest();

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

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

JSONP Request:

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

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

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.

JSON:

{ "bar": "baz" }

JSONP:

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

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).


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.


Using jQuery

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

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.


Comparable JSON/JSONP Implementations

The following assumes a response object { "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);
虐人心 2024-10-02 09:26:11

假设您有一些 URL 为您提供了 JSON 数据,例如:

{'field': 'value'}

...并且您有一个类似的 URL,只不过它使用 JSONP,您向该 URL 传递了回调函数名称“myCallback”(通常通过为其提供一个名为“callback”的查询参数来完成) ,例如http://example.com/dataSource?callback=myCallback)。然后它会返回:

myCallback({'field':'value'})

...这不仅仅是一个对象,而且实际上是可以执行的代码。因此,如果您在页面中的其他位置定义一个名为 myFunction 的函数并执行此脚本,则会使用 URL 中的数据来调用该函数。

最酷的一点是:您可以创建一个脚本标记并使用您的 URL(带有 callback 参数)作为 src 属性,浏览器将运行它。这意味着您可以绕过“同源”安全策略(因为浏览器允许您从页面域以外的源运行脚本标记)。

这就是 jQuery 在发出 ajax 请求时所做的事情(使用 .ajax 以“jsonp”作为 dataType 属性的值)。例如

$.ajax({
  url: 'http://example.com/datasource',
  dataType: 'jsonp',
  success: function(data) {
    // your code to handle data here
  }
});

,在这里,jQuery 负责处理回调函数名称和查询参数 - 使 API 与其他 ajax 调用相同。但与其他类型的 ajax 请求不同,如上所述,您不限于从与页面相同的来源获取数据。

Say you had some URL that gave you JSON data like:

{'field': 'value'}

...and you had a similar URL except it used JSONP, to which you passed the callback function name 'myCallback' (usually done by giving it a query parameter called 'callback', e.g. http://example.com/dataSource?callback=myCallback). Then it would return:

myCallback({'field':'value'})

...which is not just an object, but is actually code that can be executed. So if you define a function elsewhere in your page called myFunction and execute this script, it will be called with the data from the URL.

The cool thing about this is: you can create a script tag and use your URL (complete with callback parameter) as the src attribute, and the browser will run it. That means you can get around the 'same-origin' security policy (because browsers allow you to run script tags from sources other than the domain of the page).

This is what jQuery does when you make an ajax request (using .ajax with 'jsonp' as the value for the dataType property). E.g.

$.ajax({
  url: 'http://example.com/datasource',
  dataType: 'jsonp',
  success: function(data) {
    // your code to handle data here
  }
});

Here, jQuery takes care of the callback function name and query parameter - making the API identical to other ajax calls. But unlike other types of ajax requests, as mentioned, you're not restricted to getting data from the same origin as your page.

温柔少女心 2024-10-02 09:26:11

JSONP 是一种绕过浏览器同源策略的方法。如何?像这样:

在此处输入图像描述

此处的目标是向 otherdomain.com 发出请求,并在响应中提醒名称。通常我们会发出 AJAX 请求:

$.get('otherdomain.com', function (response) {
  var name = response.name;
  alert(name);
});

但是,由于请求发送到不同的域,因此它不起作用。

不过,我们可以使用 $.get('otherdomain.com') 都会导致相同的请求made:

GET otherdomain.com

问:但是如果我们使用

答:呃,我们不能。但这是我们可以做的 - 定义一个使用响应的函数,然后告诉服务器使用 JavaScript 进行响应,该 JavaScript 调用我们的函数并将响应作为其参数。

问:但是如果服务器不为我们执行此操作,而只愿意返回 JSON 给我们怎么办?

A: 那我们就不能使用它了。 JSONP需要服务器配合。

问:必须使用

答:像 jQuery 这样的库让它变得更好。例如:

$.ajax({
    url: "http://otherdomain.com",
    jsonp: "callback",
    dataType: "jsonp",
    success: function( response ) {
        console.log( response );
    }
});

它通过动态创建

问:

A:那么 JSONP 对我们就不起作用了。

问:没关系,我只想发出 GET 请求。 JSONP 太棒了,我要去使用它 - 谢谢!

A:事实上,这并没有那么了不起。这实际上只是一个黑客行为。而且它并不是最安全的。既然 CORS 可用,您应该尽可能使用它。

JSONP is a way of getting around the browser's same-origin policy. How? Like this:

enter image description here

The goal here is to make a request to otherdomain.com and alert the name in the response. Normally we'd make an AJAX request:

$.get('otherdomain.com', function (response) {
  var name = response.name;
  alert(name);
});

However, since the request is going out to a different domain, it won't work.

We can make the request using a <script> tag though. Both <script src="otherdomain.com"></script> and $.get('otherdomain.com') will result in the same request being made:

GET otherdomain.com

Q: But if we use the <script> tag, how could we access the response? We need to access it if we want to alert it.

A: Uh, we can't. But here's what we could do - define a function that uses the response, and then tell the server to respond with JavaScript that calls our function with the response as its argument.

Q: But what if the server won't do this for us, and is only willing to return JSON to us?

A: Then we won't be able to use it. JSONP requires the server to cooperate.

Q: Having to use a <script> tag is ugly.

A: Libraries like jQuery make it nicer. Ex:

$.ajax({
    url: "http://otherdomain.com",
    jsonp: "callback",
    dataType: "jsonp",
    success: function( response ) {
        console.log( response );
    }
});

It works by dynamically creating the <script> tag DOM element.

Q: <script> tags only make GET requests - what if we want to make a POST request?

A: Then JSONP won't work for us.

Q: That's ok, I just want to make a GET request. JSONP is awesome and I'm going to go use it - thanks!

A: Actually, it isn't that awesome. It's really just a hack. And it isn't the safest thing to use. Now that CORS is available, you should use it whenever possible.

み格子的夏天 2024-10-02 09:26:11

我发现了一篇有用的文章,它也非常清晰且简单地解释了该主题。链接是 JSONP

一些值得注意的点是:

  1. JSONP 早于 CORS。
  2. 它是一种从不同域检索数据的伪标准方法,
  3. 它具有有限的 CORS 功能(仅限 GET 方法),

工作原理如下:

  1. 当执行步骤 1 时,它会感知到具有相同函数名称(如 url 参数中给出)的函数作为响应。
  2. 如果代码中存在给定名称的函数,则将使用作为该函数的参数返回的数据(如果有)来执行该函数。

I have found a useful article that also explains the topic quite clearly and easy language. Link is JSONP

Some of the worth noting points are:

  1. JSONP pre-dates CORS.
  2. It is a pseudo-standard way to retreive data from a different domain,
  3. It has limited CORS features (only GET method)

Working is as follows:

  1. <script src="url?callback=function_name"> is included in the html code
  2. When step 1 gets executed it sens a function with the same function name (as given in the url parameter) as a response.
  3. If the function with the given name exists in the code, it will be executed with the data, if any, returned as an argument to that function.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文