Javascript 什么是 JSONP,为什么创建它?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2067472/
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-22 22:38:45  来源:igfitidea点击:

What is JSONP, and why was it created?

javascriptjsonjsonpterminology

提问by Cheeso

I understand JSON, but not JSONP. Wikipedia's document on JSONis (was) the top search result for JSONP. It says this:

我了解 JSON,但不了解 JSONP。维基百科关于 JSON 的文档是(曾经)JSONP 的顶级搜索结果。它是这样说的:

JSONP or "JSON with padding" is a JSON extension wherein a prefix is specified as an input argument of the call itself.

JSONP 或“带填充的 JSON”是 JSON 扩展,其中将前缀指定为调用本身的输入参数。

Huh? What call? That doesn't make any sense to me. JSON is a data format. There's no call.

嗯?什么叫?这对我来说没有任何意义。JSON 是一种数据格式。没有电话。

The 2nd search resultis from some guy named Remy, who writes this about JSONP:

第二个搜索结果是由某些人叫雷米,谁写的这个约JSONP:

JSONP is script tag injection, passing the response from the server in to a user specified function.

JSONP 是脚本标记注入,将来自服务器的响应传递给用户指定的函数。

I can sort of understand that, but it's still not making any sense.

我可以理解这一点,但它仍然没有任何意义。



So what is JSONP? Why was it created (what problem does it solve)? And why would I use it?

那么什么是 JSONP?为什么创建它(它解决了什么问题)?我为什么要使用它?



Addendum: I've just created a new page for JSONPon Wikipedia; it now has a clear and thorough description of JSONP, based on jvenema's answer.

附录:我刚刚在维基百科上为 JSONP创建了一个新页面;它现在根据jvenema的回答对 JSONP 进行了清晰而彻底的描述。

采纳答案by jvenema

It's actually not too complicated...

其实也不是很复杂...

Say you're on domain example.com, and you want to make a request to domain example.net. To do so, you need to cross domainboundaries, a no-noin most of browserland.

假设您在 domain 上example.com,并且您想向 domain 发出请求example.net。要做到这一点,你需要跨域边界,一个没有没有在大多数browserland的。

The one item that bypasses this limitation is <script>tags. When you use a script tag, the domain limitation is ignored, but under normal circumstances, you can't really doanything with the results, the script just gets evaluated.

绕过此限制的一项是<script>标签。当您使用脚本标签时,域限制被忽略,但在正常情况下,您无法真正对结果任何事情,脚本只是被评估。

Enter JSONP. When you make your request to a server that is JSONP enabled, you pass a special parameter that tells the server a little bit about your page. That way, the server is able to nicely wrap up its response in a way that your page can handle.

输入JSONP。当您向启用 JSONP 的服务器发出请求时,您会传递一个特殊参数,该参数会告诉服务器有关您的页面的一些信息。这样,服务器就能够以您的页面可以处理的方式很好地包装其响应。

For example, say the server expects a parameter called callbackto enable its JSONP capabilities. Then your request would look like:

例如,假设服务器需要调用一个参数callback来启用其 JSONP 功能。那么您的请求将如下所示:

http://www.example.net/sample.aspx?callback=mycallback

Without JSONP, this might return some basic JavaScript object, like so:

如果没有 JSONP,这可能会返回一些基本的 JavaScript 对象,如下所示:

{ foo: 'bar' }

However, with JSONP, when the server receives the "callback" parameter, it wraps up the result a little differently, returning something like this:

但是,对于 JSONP,当服务器收到“回调”参数时,它会以稍微不同的方式包装结果,返回如下内容:

mycallback({ foo: 'bar' });

As you can see, it will now invoke the method you specified. So, in your page, you define the callback function:

如您所见,它现在将调用您指定的方法。因此,在您的页面中,您定义回调函数:

mycallback = function(data){
  alert(data.foo);
};

And now, when the script is loaded, it'll be evaluated, and your function will be executed. Voila, cross-domain requests!

现在,当脚本被加载时,它会被评估,你的函数将被执行。瞧,跨域请求!

It's also worth noting the one major issue with JSONP: you lose a lot of control of the request. For example, there is no "nice" way to get proper failure codes back. As a result, you end up using timers to monitor the request, etc, which is always a bit suspect. The proposition for JSONRequestis a great solution to allowing cross domain scripting, maintaining security, and allowing proper control of the request.

还值得注意的是 JSONP 的一个主要问题:您失去了对请求的很多控制。例如,没有“好”的方法来获取正确的故障代码。结果,您最终使用计时器来监视请求等,这总是有点可疑。JSONRequest的提议是允许跨域脚本编写、维护安全性和允许正确控制请求的一个很好的解决方案。

These days (2015), CORSis the recommended approach vs. JSONRequest. JSONP is still useful for older browser support, but given the security implications, unless you have no choice CORS is the better choice.

如今(2015 年),与 JSONRequest 相比,CORS是推荐的方法。JSONP 对于较旧的浏览器支持仍然有用,但考虑到安全隐患,除非您别无选择,否则 CORS 是更好的选择。

回答by ThatGuy

JSONPis really a simple trick to overcome the XMLHttpRequestsame domain policy. (As you know one cannot send AJAX (XMLHttpRequest)request to a different domain.)

JSONP确实是克服XMLHttpRequest同域策略的简单技巧。(如您所知,不能将AJAX (XMLHttpRequest)请求发送到不同的域。)

So - instead of using XMLHttpRequestwe have to use scriptHTML tags, the ones you usually use to load js files, in order for js to get data from another domain. Sounds weird?

所以 -我们必须使用脚本HTML 标签而不是使用XMLHttpRequest,您通常使用这些标签来加载 js 文件,以便 js 从另一个域获取数据。听起来怪怪的?

Thing is - turns out scripttags can be used in a fashion similar to XMLHttpRequest! Check this out:

事实是 -脚本标签可以以类似于XMLHttpRequest的方式使用!看一下这个:

script = document.createElement('script');
script.type = 'text/javascript';
script.src = 'http://www.someWebApiServer.com/some-data';

You will end up with a scriptsegment that looks like this after it loads the data:

加载数据后,您将得到一个如下所示的脚本段:

<script>
{['some string 1', 'some data', 'whatever data']}
</script>

However this is a bit inconvenient, because we have to fetch this array from scripttag. So JSONPcreators decided that this will work better(and it is):

然而这有点不方便,因为我们必须从脚本标签中获取这个数组。所以JSONP创建者决定这会更好(而且确实如此):

script = document.createElement('script');
script.type = 'text/javascript';
script.src = 'http://www.someWebApiServer.com/some-data?callback=my_callback';

Notice the my_callbackfunction over there? So - when JSONPserver receives your request and finds callback parameter - instead of returning plain js array it'll return this:

注意到那边的 my_callback函数了吗?所以 - 当JSONP服务器收到您的请求并找到回调参数时 - 它不会返回普通的 js 数组,而是返回:

my_callback({['some string 1', 'some data', 'whatever data']});

See where the profit is:now we get automatic callback (my_callback) that'll be triggered once we get the data.
That's all there is to know about JSONP: it's a callback and script tags.

看看利润在哪里:现在我们得到了自动回调(my_callback),一旦我们得到数据就会被触发。
这就是关于JSONP的全部知识:它是一个回调和脚本标签。

NOTE: these are simple examples of JSONP usage, these are not production ready scripts.

注意:这些是 JSONP 用法的简单示例,这些不是生产就绪脚本。

Basic JavaScript example (simple Twitter feed using JSONP)

基本 JavaScript 示例(使用 JSONP 的简单 Twitter 提要)

<html>
    <head>
    </head>
    <body>
        <div id = 'twitterFeed'></div>
        <script>
        function myCallback(dataWeGotViaJsonp){
            var text = '';
            var len = dataWeGotViaJsonp.length;
            for(var i=0;i<len;i++){
                twitterEntry = dataWeGotViaJsonp[i];
                text += '<p><img src = "' + twitterEntry.user.profile_image_url_https +'"/>' + twitterEntry['text'] + '</p>'
            }
            document.getElementById('twitterFeed').innerHTML = text;
        }
        </script>
        <script type="text/javascript" src="http://twitter.com/status/user_timeline/padraicb.json?count=10&callback=myCallback"></script>
    </body>
</html>

Basic jQuery example (simple Twitter feed using JSONP)

基本 jQuery 示例(使用 JSONP 的简单 Twitter 提要)

<html>
    <head>
        <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
        <script>
            $(document).ready(function(){
                $.ajax({
                    url: 'http://twitter.com/status/user_timeline/padraicb.json?count=10',
                    dataType: 'jsonp',
                    success: function(dataWeGotViaJsonp){
                        var text = '';
                        var len = dataWeGotViaJsonp.length;
                        for(var i=0;i<len;i++){
                            twitterEntry = dataWeGotViaJsonp[i];
                            text += '<p><img src = "' + twitterEntry.user.profile_image_url_https +'"/>' + twitterEntry['text'] + '</p>'
                        }
                        $('#twitterFeed').html(text);
                    }
                });
            })
        </script>
    </head>
    <body>
        <div id = 'twitterFeed'></div>
    </body>
</html>


JSONPstands for JSON with Padding. (very poorly named technique as it really has nothing to do with what most people would think of as “padding”.)


JSONP代表带 Padding 的 JSON。(非常糟糕的技术,因为它实际上与大多数人认为的“填充”无关。)

回答by Ajain Vivek

JSONP works by constructing a “script” element (either in HTML markup or inserted into the DOM via JavaScript), which requests to a remote data service location. The response is a javascript loaded on to your browser with name of the pre-defined function along with parameter being passed that is tht JSON data being requested. When the script executes, the function is called along with JSON data, allowing the requesting page to receive and process the data.

JSONP 通过构建一个“脚本”元素(在 HTML 标记中或通过 JavaScript 插入到 DOM 中)来工作,该元素向远程数据服务位置请求。响应是加载到浏览器的 javascript,带有预定义函数的名称以及传递的参数,即请求的 JSON 数据。当脚本执行时,该函数与 JSON 数据一起被调用,允许请求页面接收和处理数据。

For Further Reading Visit:https://blogs.sap.com/2013/07/15/secret-behind-jsonp/

进一步阅读访问:https : //blogs.sap.com/2013/07/15/secret-behind-jsonp/

client side snippet of code

客户端代码片段

    <!DOCTYPE html>
    <html lang="en">
    <head>
     <title>AvLabz - CORS : The Secrets Behind JSONP </title>
     <meta charset="UTF-8" />
    </head>
    <body>
      <input type="text" id="username" placeholder="Enter Your Name"/>
      <button type="submit" onclick="sendRequest()"> Send Request to Server </button>
    <script>
    "use strict";
    //Construct the script tag at Runtime
    function requestServerCall(url) {
      var head = document.head;
      var script = document.createElement("script");

      script.setAttribute("src", url);
      head.appendChild(script);
      head.removeChild(script);
    }

    //Predefined callback function    
    function jsonpCallback(data) {
      alert(data.message); // Response data from the server
    }

    //Reference to the input field
    var username = document.getElementById("username");

    //Send Request to Server
    function sendRequest() {
      // Edit with your Web Service URL
      requestServerCall("http://localhost/PHP_Series/CORS/myService.php?callback=jsonpCallback&message="+username.value+"");
    }    

  </script>
   </body>
   </html>

Server side piece of PHP code

服务器端一段 PHP 代码

<?php
    header("Content-Type: application/javascript");
    $callback = $_GET["callback"];
    $message = $_GET["message"]." you got a response from server yipeee!!!";
    $jsonResponse = "{\"message\":\"" . $message . "\"}";
    echo $callback . "(" . $jsonResponse . ")";
?>

回答by jldupont

Because you can ask the server to prepend a prefix to the returned JSON object. E.g

因为您可以要求服务器为返回的 JSON 对象添加前缀。例如

function_prefix(json_object);

function_prefix(json_object);

in order for the browser to eval"inline" the JSON string as an expression. This trick makes it possible for the server to "inject" javascript code directly in the Client browser and this with bypassing the "same origin" restrictions.

为了让浏览器eval将 JSON 字符串“内联”为表达式。这个技巧使服务器可以直接在客户端浏览器中“注入”javascript代码,并绕过“同源”限制。

In other words, you can achieve cross-domain data exchange.

也就是说,可以实现跨域的数据交换



Normally, XMLHttpRequestdoesn't permit cross-domain data-exchange directly (one needs to go through a server in the same domain) whereas:

通常,XMLHttpRequest不允许直接跨域数据交换(需要通过同一域中的服务器),而:

<script src="some_other_domain/some_data.js&prefix=function_prefix>` one can access data from a domain different than from the origin.

<script src="some_other_domain/some_data.js&prefix=function_prefix>` 可以访问来自与源不同的域的数据。



Also worth noting: even though the server should be considered as "trusted" before attempting that sort of "trick", the side-effects of possible change in object format etc. can be contained. If a function_prefix(i.e. a proper js function) is used to receive the JSON object, the said function can perform checks before accepting/further processing the returned data.

还值得注意的是:即使在尝试这种“技巧”之前应该将服务器视为“受信任的”,但可以包含对象格式等可能更改的副作用。如果使用a function_prefix(即适当的js 函数)来接收JSON 对象,则该函数可以在接受/进一步处理返回的数据之前执行检查。

回答by dardawk

JSONP is a great away to get around cross-domain scripting errors. You can consume a JSONP service purely with JS without having to implement a AJAX proxy on the server side.

JSONP 是解决跨域脚本错误的好方法。您可以纯粹使用 JS 来使用 JSONP 服务,而无需在服务器端实现 AJAX 代理。

You can use the b1t.coservice to see how it works. This is a free JSONP service that alllows you to minify your URLs. Here is the url to use for the service:

您可以使用b1t.co服务来查看它是如何工作的。这是一个免费的 JSONP 服务,允许您缩小您的 URL。这是用于该服务的网址:

http://b1t.co/Site/api/External/MakeUrlWithGet?callback=[resultsCallBack]&url=[escapedUrlToMinify]

http://b1t.co/Site/api/External/MakeUrlWithGet?callback=[resultsCallBack]&url=[escapedUrlToMinify]

For example the call, http://b1t.co/Site/api/External/MakeUrlWithGet?callback=whateverJavascriptName&url=google.com

例如调用,http://b1t.co/Site/api/External/MakeUrlWithGet?callback=whateverJavascriptName&url=google.com

would return

会回来

whateverJavascriptName({"success":true,"url":"http://google.com","shortUrl":"http://b1t.co/54"});

And thus when that get's loaded in your js as a src, it will automatically run whateverJavascriptName which you should implement as your callback function:

因此,当该 get 作为 src 加载到您的 js 中时,它将自动运行您应该作为回调函数实现的任何JavascriptName:

function minifyResultsCallBack(data)
{
    document.getElementById("results").innerHTML = JSON.stringify(data);
}

To actually make the JSONP call, you can do it about several ways (including using jQuery) but here is a pure JS example:

要实际进行 JSONP 调用,您可以通过多种方式(包括使用 jQuery)进行调用,但这里是一个纯 JS 示例:

function minify(urlToMinify)
{
   url = escape(urlToMinify);
   var s = document.createElement('script');
   s.id = 'dynScript';
   s.type='text/javascript';
   s.src = "http://b1t.co/Site/api/External/MakeUrlWithGet?callback=resultsCallBack&url=" + url;
   document.getElementsByTagName('head')[0].appendChild(s);
}

A step by step example and a jsonp web service to practice on is available at: this post

一个分步示例和一个用于练习的 jsonp Web 服务可在以下位置获得:这篇文章

回答by sarath joseph

A simple example for the usage of JSONP.

JSONP 使用的简单示例。

client.html

客户端.html

    <html>
    <head>
   </head>
     body>


    <input type="button" id="001" onclick=gO("getCompany") value="Company"  />
    <input type="button" id="002" onclick=gO("getPosition") value="Position"/>
    <h3>
    <div id="101">

    </div>
    </h3>

    <script type="text/javascript">

    var elem=document.getElementById("101");

    function gO(callback){

    script = document.createElement('script');
    script.type = 'text/javascript';
    script.src = 'http://localhost/test/server.php?callback='+callback;
    elem.appendChild(script);
    elem.removeChild(script);


    }

    function getCompany(data){

    var message="The company you work for is "+data.company +"<img src='"+data.image+"'/   >";
    elem.innerHTML=message;
}

    function getPosition(data){
    var message="The position you are offered is "+data.position;
    elem.innerHTML=message;
    }
    </script>
    </body>
    </html>

server.php

服务器.php

  <?php

    $callback=$_GET["callback"];
    echo $callback;

    if($callback=='getCompany')
    $response="({\"company\":\"Google\",\"image\":\"xyz.jpg\"})";

    else
    $response="({\"position\":\"Development Intern\"})";
    echo $response;

    ?>    

回答by Marcus Thornton

Before understanding JSONP, you need to know JSON format and XML. Currently the most frequently used data format on the web is XML, but XML is very complicated. It makes users inconvenient to process embedded in Web pages.

在了解 JSONP 之前,您需要了解 JSON 格式和 XML。目前网络上最常用的数据格式是 XML,但 XML 非常复杂。它使用户不方便处理嵌入在网页中。

To make JavaScript can easily exchange data, even as the data processing program, we use the wording according to JavaScript objects and developed a simple data exchange format, which is JSON. JSON can be used as data, or as a JavaScript program.

为了让 JavaScript 可以方便地交换数据,甚至作为数据处理程序,我们根据 JavaScript 对象使用措辞,并开发了一种简单的数据交换格式,即 JSON。JSON 可以用作数据,也可以用作 JavaScript 程序。

JSON can be directly embedded in JavaScript, using them you can directly execute certain JSON program, but due to security constraints, the browser Sandbox mechanism disables cross-domain JSON code execution.

JSON 可以直接嵌入到 JavaScript 中,使用它们可以直接执行某些 JSON 程序,但是由于安全限制,浏览器沙箱机制禁用了跨域 JSON 代码执行。

To make JSON can be passed after the execution, we developed a JSONP. JSONP bypass the security limits of the browser with JavaScript Callback functionality and the < script > tag.

为了让JSON在执行后可以通过,我们开发了一个JSONP。JSONP 通过 JavaScript 回调功能和 <script> 标签绕过浏览器的安全限制。

So in short it explains what JSONP is, what problem it solves (when to use it).

所以简而言之,它解释了 JSONP 是什么,它解决了什么问题(何时使用它)。

回答by Humoyun Ahmad

The great answers have already been given, I just need to give my piece in the form of code blocks in javascript (I will also include more modern and better solution for cross-origin requests: CORS with HTTP Headers):

已经给出了很好的答案,我只需要在 javascript 中以代码块的形式给出我的作品(我还将包括更现代和更好的跨域请求解决方案:CORS with HTTP Headers):

JSONP:

JSONP:

1.client_jsonp.js

1.client_jsonp.js

$.ajax({
    url: "http://api_test_server.proudlygeek.c9.io/?callback=?",
    dataType: "jsonp",
    success: function(data) {
        console.log(data);    
    }
});??????????????????

2.server_jsonp.js

2.server_jsonp.js

var http = require("http"),
    url  = require("url");

var server = http.createServer(function(req, res) {

    var callback = url.parse(req.url, true).query.callback || "myCallback";
    console.log(url.parse(req.url, true).query.callback);

    var data = {
        'name': "Gianpiero",
        'last': "Fiorelli",
        'age': 37
    };

    data = callback + '(' + JSON.stringify(data) + ');';

    res.writeHead(200, {'Content-Type': 'application/json'});
    res.end(data);
});

server.listen(process.env.PORT, process.env.IP);

console.log('Server running at '  + process.env.PORT + ':' + process.env.IP);

CORS:

科尔斯

3.client_cors.js

3.client_cors.js

$.ajax({
    url: "http://api_test_server.proudlygeek.c9.io/",
    success: function(data) {
        console.log(data);    
    }
});?

4.server_cors.js

4.server_cors.js

var http = require("http"),
    url  = require("url");

var server = http.createServer(function(req, res) {
    console.log(req.headers);

    var data = {
        'name': "Gianpiero",
        'last': "Fiorelli",
        'age': 37
    };

    res.writeHead(200, {
        'Content-Type': 'application/json',
        'Access-Control-Allow-Origin': '*'
    });

    res.end(JSON.stringify(data));
});

server.listen(process.env.PORT, process.env.IP);

console.log('Server running at '  + process.env.PORT + ':' + process.env.IP);

回答by Carles Alcolea

TL;DR

TL; 博士

JSONP is an old trickinvented to bypass the security restriction that forbids us to get JSON data from a different server (a different origin*).

JSONP 是一种古老的技巧,旨在绕过禁止我们从不同服务器(不同来源*)获取 JSON 数据的安全限制。

The trick works by using a <script>tag that asks for the JSON from that place, e.g.: { "user":"Smith" }, but wrapped in a function, the actual JSONP("JSON with Padding"):

该技巧的工作原理是使用<script>从该位置请求 JSON的标签,例如: { "user":"Smith" },但包装在一个函数中,即实际的 JSONP(“带填充的 JSON”):

peopleDataJSONP({"user":"Smith"})

Receiving it in this form enables us to use the data within our peopleDataJSONPfunction. JSONP is a bad practice, don't use it (read below)

以这种形式接收它使我们能够在我们的peopleDataJSONP函数中使用数据。JSONP 是一个不好的做法,不要使用它(阅读下文)



The problem

问题

Say we're navigating on ourweb.com, and we want to get JSON data (or any raw data really) from anotherweb.com. If we were to use GET request (like XMLHttpRequest, a fetchcall, $.ajax, etc.), our browser would tell us it's not allowed with this ugly error:

假设我们在 上导航ourweb.com,并且我们想从anotherweb.com. 如果我们要使用 GET 请求(例如XMLHttpRequestfetch调用,$.ajax等等),我们的浏览器会告诉我们这个丑陋的错误是不允许的:

Chrome CORS console error

Chrome CORS 控制台错误

How to get the data we want? Well, <script>tags are not subjected to this whole server (origin*) restriction! That's why we can load a library like jQuery or Google Maps from any server, such as a CDN, without any errors.

如何获取我们想要的数据?好吧,<script>标签不受整个服务器(来源*)的限制!这就是为什么我们可以从任何服务器(例如 CDN)加载 jQuery 或 Google Maps 之类的库而不会出现任何错误的原因。

Important point: if you think about it, those libraries are actual, runnable JS code(usually a massive function with all the logic inside). But raw data? JSON data is not code. There's nothing to run; it's just plain data.

重要的一点:如果你仔细想想,这些库是实际的、可运行的 JS 代码(通常是一个包含所有逻辑的庞大函数)。但是原始数据呢?JSON 数据不是代码。没有什么可跑的;这只是简单的数据。

Therefore, there's no way to handle or manipulate our precious data. The browser will download the data pointed at by our <script>tag and when processing it'll rightfully complain:

因此,没有办法处理或操纵我们的宝贵数据。浏览器将下载我们的<script>标签指向的数据,并在处理时正确地抱怨:

wtf is this {"user":"Smith"}crap we loaded? It's not code. I can't compute, syntax error!

wtf 这是{"user":"Smith"}我们加载的垃圾吗?这不是代码。我无法计算,语法错误!



The JSONP hack

JSONP 黑客

The old/hacky way to utilize that data? We need that server to send it with some logic, so when it's loaded, your code in the browser will be able to use said data. So the foreign server sends us the JSON data inside a JS function. The data itself is set up as that function's input. It looks like this:

使用该数据的旧/hacky 方式?我们需要该服务器以某种逻辑发送它,因此当它加载时,浏览器中的代码将能够使用所述数据。因此,外部服务器在 JS 函数中向我们发送 JSON 数据。数据本身被设置为该函数的输入。它看起来像这样:

peopleDataJSONP({"user":"Smith"})

which makes it JS codeour browser will parse without complaining! Exactly like it does with the jQuery library. Now, to get it like that, the client "asks" the JSONP-friendly server for it, usually done like this:

这使得我们的浏览器可以毫无怨言地解析JS 代码!与 jQuery 库完全一样。现在,为了得到它,客户端“询问”JSONP 友好的服务器,通常是这样完成的:

<script src="https://anotherweb.com/api/data-from-people.json?myCallback=peopleDataJSONP"></script>

Our browser will receive the JSONP with that function name, hence we need a function with the same name in our code, like this:

我们的浏览器将接收具有该函数名称的 JSONP,因此我们的代码中需要一个具有相同名称的函数,如下所示:

const peopleDataJSONP = function(data){
  alert(data.user); // "Smith"
}

Or like this, same outcome:

或者像这样,同样的结果:

function peopleDataJSONP(data){
  alert(data.user); // "Smith"
}

The browser will download the JSONP and run it, which calls our function, where the argument datawill be our JSON. We can now do with our data whatever we want to.

浏览器将下载 JSONP 并运行它,它调用我们的 function,其中参数data将是我们的 JSON。我们现在可以对我们的数据做任何我们想做的事情。



Don't use JSONP, use CORS

不要使用 JSONP,使用 CORS

JSONP is a cross-site hack with a few downsides:

JSONP 是一种跨站点黑客攻击,有一些缺点:

  • We can only perform GET requests
  • Since it's a GET request triggered by a simple script tag, we don't get helpful errors or progress info
  • There are also some security concerns, like running in your client JS code that could be changed to a malicious payload
  • It only solves the problem with JSON data, but Same-Origin security policy applies to other data (WebFonts, images/video drawn with drawImage()...)
  • It's not very elegant nor readable.
  • 我们只能执行 GET 请求
  • 由于它是由一个简单的脚本标记触发的 GET 请求,因此我们不会收到有用的错误或进度信息
  • 还有一些安全问题,例如在您的客户端 JS 代码中运行可能会更改为恶意负载
  • 它只解决了 JSON 数据的问题,但同源安全策略适用于其他数据(WebFonts、使用 drawImage() 绘制的图像/视频...)
  • 它不是很优雅,也不是很可读。

The takeaway is that there's no need to use it nowadays.

要点是现在没有必要使用它

JSONP is the trick to get JSON data from another server, but we'll violate the same security principle (Same-Origin) if we need other kinds of cross-site stuff.

JSONP 是从另一台服务器获取 JSON 数据的技巧,但如果我们需要其他类型的跨站点内容,我们将违反相同的安全原则(同源)。

You should read about CORS here, but the gist of it is:

您应该在此处阅读有关 CORS 的信息,但其要点是:

Cross-Origin Resource Sharing (CORS) is a mechanism that uses additional HTTP headers to tell browsers to give a web application running at one origin, access to selected resources from a different origin. A web application executes a cross-origin HTTP request when it requests a resource that has a different origin (domain, protocol, or port) from its own.

跨域资源共享 (CORS) 是一种机制,它使用额外的 HTTP 标头告诉浏览器让在一个源上运行的 Web 应用程序可以访问来自不同源的选定资源。当 Web 应用程序请求与自身具有不同来源(域、协议或端口)的资源时,它会执行跨源 HTTP 请求。





*origin is defined by 3 things: protocol, port, and host. So, for example, https://web.comis a different origin than http://web.com(different protocol) and https://web.com:8081(different port) and obviously https://thatotherweb.net(different host)

*origin 由三件事定义:protocolporthost。因此,例如,https://web.com是与http://web.com(不同的协议)和https://web.com:8081(不同的端口)和显然https://thatotherweb.net(不同的主机)不同的来源

回答by simhumileco

JSONPstands for JSONwith Padding.

JSONP代表带Padding 的JSON

Here is the site, with great examples, with the explanation from the simplest useof this technique to the most advancedin plane JavaScript:

这是网站,有很好的例子从最简单的使用这种技术到最先进的平面 JavaScript 的解释:

w3schools.com / JSONP

w3schools.com / JSONP

One of my more favorite techniques described above is Dynamic JSON Result, which allow to send JSON to the PHP file in URL parameter, and let the PHP file also return a JSON object based on the information it gets.

上面描述的我最喜欢的技术之一是动态 JSON 结果,它允许将 JSON 发送到 URL 参数中PHP 文件,并让PHP 文件也根据它获得的信息返回一个 JSON 对象

Tools like jQuery also have facilities to use JSONP:

jQuery这样的工具也有使用 JSONP 的工具

jQuery.ajax({
  url: "https://data.acgov.org/resource/k9se-aps6.json?city=Berkeley",
  jsonp: "callbackName",
  dataType: "jsonp"
}).done(
  response => console.log(response)
);