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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3839966/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 16:12:52  来源:igfitidea点击:

Can anyone explain what JSONP is, in layman terms?

jqueryjsonp

提问by Someone

I know JSONPis JSONwith padding.

我知道JSONPJSON用填充。

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

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

Can anyone explain to me how this works?

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

回答by Matt

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 serveror APIsupports it, and the browser supportis adequate), as JSONP has inherent security risks.

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



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

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

JSON and JSONP behave differently on the client and the server. JSONP requests are not dispatched using the XMLHTTPRequestand 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 和 JSONP 在客户端和服务器上的行为不同。JSONP 请求不会使用XMLHTTPRequest和相关的浏览器方法分派。而是<script>创建一个标记,其源设置为目标 URL。然后将此脚本标记添加到 DOM(通常在<head>元素内部)。

JSON Request:

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 Request:

JSONP 请求:

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 响应和 JSONP 响应之间的区别在于 JSONP 响应对象作为参数传递给回调函数。

JSON:

JSON:

{ "bar": "baz" }

JSONP:

JSONP:

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


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

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

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

此功能必须存在于全球范围内的时间<script>标记是由浏览器进行评估(一旦请求已完成)。



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.

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

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

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



Using jQuery

使用 jQuery

The usefulness of using jQueryto make JSONP requests, is that jQuery does all of the workfor you in the background.

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

By default jQuery requires you to include &callback=?in the URL of your AJAX request. jQuery will take the successfunction 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.

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



Comparable JSON/JSONP Implementations

可比较的 JSON/JSONP 实现

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

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

JSON:

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:

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

回答by sje397

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

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

{'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:

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

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 myFunctionand execute this script, it will be called with the data from the URL.

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

The cool thing about this is: you can create a script tag and use your URL (complete with callbackparameter) as the srcattribute, 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).

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

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

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

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

在这里,jQuery 负责回调函数名称和查询参数 - 使 API 与其他 ajax 调用相同。但与前面提到的其他类型的 ajax 请求不同的是,您并不仅限于从与您的页面相同的来源获取数据。

回答by Adam Zerner

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

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

enter image description here

在此处输入图片说明

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

这里的目标是使一个请求otherdomain.com,并alert在响应中的名称。通常我们会发出一个 AJAX 请求:

$.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:

不过,我们可以使用<script>标签发出请求。双方<script src="otherdomain.com"></script>$.get('otherdomain.com')会导致相同的请求而作出:

GET otherdomain.com

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

问:但是如果我们使用<script>标签,我们如何访问响应?如果我们想访问它,我们需要访问alert它。

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.

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

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

Q:但是如果服务器不给我们做这个,只愿意返回JSON给我们怎么办?

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

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

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

问:必须使用<script>标签是丑陋的。

A: Libraries like jQuery make it nicer. Ex:

A:像 jQuery这样的让它变得更好。前任:

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

它通过动态创建<script>标签 DOM 元素来工作。

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

问:<script>标签只发出 GET 请求 - 如果我们想发出 POST 请求怎么办?

A: Then JSONP won't work for us.

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

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

问:没关系,我只是想发出一个 GET 请求。JSONP 很棒,我会去使用它 - 谢谢!

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

A:实际上,它并不是那么棒。这真的只是一个黑客。而且这不是最安全的使用方法。现在 CORS 可用,您应该尽可能使用它。

回答by Harshit Garg

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

我找到了一篇有用的文章,它也用非常清晰和简单的语言解释了这个主题。链接是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)
  1. JSONP 早于 CORS。
  2. 这是一种从不同域检索数据的伪标准方法,
  3. 它具有有限的 CORS 功能(仅限 GET 方法)

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.
  1. <script src="url?callback=function_name">包含在 html 代码中
  2. 当第 1 步被执行时,它会检测一个具有相同函数名称(如 url 参数中给出的)的函数作为响应。
  3. 如果代码中存在具有给定名称的函数,则将使用数据(如果有)作为该函数的参数返回来执行该函数。