【问题标题】:What are the differences between JSON and JSONP?JSON 和 JSONP 有什么区别?
【发布时间】:2011-02-22 15:39:34
【问题描述】:

格式、文件类型和实际使用?

【问题讨论】:

  • 一种方法比另一种更快吗?例如,如果您使用 XMLHttpRequest 来获取请求(显然是到同一个域,因为它是“普通”ajax),或者如果您使用 JSONP 方法(不会使用 XMLHTTPRequest) - 会比另一个更快吗?我知道这取决于几个因素 - 但有人做过速度比较吗?

标签: json jsonp javascript


【解决方案1】:

JSONP 是带有填充的 JSON。也就是说,您在开头放置一个字符串,并在其周围放置一对括号。例如:

//JSON
{"name":"stackoverflow","id":5}
//JSONP
func({"name":"stackoverflow","id":5});

结果是您可以将 JSON 作为脚本文件加载。如果您之前设置了一个名为 func 的函数,那么当脚本文件加载完成时,该函数将使用一个参数调用,即 JSON 数据。这通常用于允许使用 JSON 数据进行跨站点 AJAX。如果您知道 example.com 正在提供类似于上面给出的 JSONP 示例的 JSON 文件,那么您可以使用这样的代码来检索它,即使您不在 example.com 域中:

function func(json){
  alert(json.name);
}
var elm = document.createElement("script");
elm.setAttribute("type", "text/javascript");
elm.src = "http://example.com/jsonp";
document.body.appendChild(elm);

【讨论】:

  • 假设您可以配置 CORS 以允许跨源请求,那么 JSONP 是否还有意义?
  • 可能有点晚了,但是我想为其他人回答您的问题,不,如果您使用 JSONP,您将忽略所有 CORS 优势(由于安全问题,我称之为优势。)我建议您正确实施 CORS,这将帮助您解决安全问题以及更好的架构方法。
【解决方案2】:

基本上,由于同源策略,您不能通过 AJAX 从另一个域请求 JSON 数据。 AJAX 允许您在页面加载后获取数据,然后在返回后执行一些代码/调用函数。我们不能使用 AJAX,但我们可以将<script> 标签注入我们自己的页面,并且这些标签可以引用托管在其他域的脚本。

通常您会使用它来包含来自 CDN 的库,例如 jQuery。但是,我们可以滥用它并使用它来获取数据! JSON 已经是有效的 JavaScript (for the most part),但我们不能只在我们的脚本文件中返回 JSON,因为我们无法知道脚本/数据何时完成加载,也无法访问它,除非它被分配到变量或传递给函数。因此,我们要做的是告诉 Web 服务在准备好时代表我们调用一个函数。

例如,我们可能会从证券交易所 API 请求一些数据,并连同我们常用的 API 参数一起,给它一个回调,例如 ?callback=callThisWhenReady。然后,Web 服务用我们的函数包装数据并像这样返回它:callThisWhenReady({...data...})。现在,一旦脚本加载,您的浏览器将尝试执行它(正常),然后调用我们的任意函数并为我们提供我们想要的数据。

它的工作方式与普通的 AJAX 请求非常相似,只是我们必须使用命名函数,而不是调用匿名函数。

jQuery 实际上通过为您创建一个唯一命名的函数并将其传递给您,从而为您无缝地支持这一点,然后依次运行您想要的代码。

【讨论】:

  • 与什么分开? JSON 也不是一种语言
  • @nickf:是的...我正在寻找合适的词...那你会怎么称呼它?根据 json.org 的“数据交换格式”。
  • 或更具可读性:JSON:“文本表示法”中的 javascript 对象。就像你可能会 toString() 一个 Java 对象一样?
  • FWIW:@SamVloeberghs - 说 JSON 代表 javascript 对象有点误导。它可以是来自任何语言或数据库的任何数据,可以表示为名称-值对和数组。并且需要额外的约定来准确地往返 any JS 对象 - 请参阅 JSON: Unsupported native data types。值得注意的是,JS Date 在远端以字符串形式返回。 weblog.west-wind.com/posts/2014/jan/06/…
【解决方案3】:

JSONP 允许您指定传递给您的 JSON 对象的回调函数。这允许您绕过同源策略并将 JSON 从外部服务器加载到网页上的 JavaScript 中。

【讨论】:

    【解决方案4】:

    JSONP 代表“带有填充的 JSON”,它是一种从不同域加载数据的解决方法。它将脚本加载到 DOM 的头部,因此您可以像在自己的域中加载一样访问信息,从而绕过跨域问题。

    jsonCallback(
    {
        "sites":
        [
            {
                "siteName": "JQUERY4U",
                "domainName": "http://www.jquery4u.com",
                "description": "#1 jQuery Blog for your Daily News, Plugins, Tuts/Tips & Code Snippets."
            },
            {
                "siteName": "BLOGOOLA",
                "domainName": "http://www.blogoola.com",
                "description": "Expose your blog to millions and increase your audience."
            },
            {
                "siteName": "PHPSCRIPTS4U",
                "domainName": "http://www.phpscripts4u.com",
                "description": "The Blog of Enthusiastic PHP Scripters"
            }
        ]
    });
    
    (function($) {
    var url = 'http://www.jquery4u.com/scripts/jquery4u-sites.json?callback=?';
    
    $.ajax({
       type: 'GET',
        url: url,
        async: false,
        jsonpCallback: 'jsonCallback',
        contentType: "application/json",
        dataType: 'jsonp',
        success: function(json) {
           console.dir(json.sites);
        },
        error: function(e) {
           console.log(e.message);
        }
    });
    
    })(jQuery);
    

    现在我们可以使用 JSONP 和我们围绕 JSON 内容创建的回调函数通过 AJAX 请求 JSON。 输出应该是 JSON 作为一个对象,然后我们可以不受限制地将数据用于我们想要的任何东西。

    【讨论】:

      【解决方案5】:

      JSONP 本质上是带有额外代码的 JSON,就像包裹数据的函数调用。它允许在解析期间对数据进行操作。

      【讨论】:

        【解决方案6】:

        JSON

        JSON(JavaScript 对象表示法) 是一种在应用程序之间传输数据的便捷方式,尤其是当目标是 JavaScript 应用程序时。

        示例:

        这是一个使用 JSON 作为服务器响应传输的最小示例。客户端使用 jQuery 速记函数 $.getJSON 发出 Ajax 请求。服务器生成一个散列,将其格式化为 JSON 并将其返回给客户端。客户端对此进行格式化并将其放入页面元素中。

        服务器:

        get '/json' do
         content_type :json
         content = { :response  => 'Sent via JSON',
                    :timestamp => Time.now,
                    :random    => rand(10000) }
         content.to_json
        end
        

        客户:

        var url = host_prefix + '/json';
        $.getJSON(url, function(json){
          $("#json-response").html(JSON.stringify(json, null, 2));
        });
        

        输出:

          {
           "response": "Sent via JSON",
           "timestamp": "2014-06-18 09:49:01 +0000",
           "random": 6074
          }
        

        JSONP(带填充的 JSON)

        JSONP 是一种在从客户端发送来自不同域的 JSON 响应时克服浏览器限制的简单方法。

        在客户端使用 JSONP 的唯一变化是在 URL 中添加回调参数

        服务器:

        get '/jsonp' do
         callback = params['callback']
         content_type :js
         content = { :response  => 'Sent via JSONP',
                    :timestamp => Time.now,
                    :random    => rand(10000) }
         "#{callback}(#{content.to_json})"
        end
        

        客户:

        var url = host_prefix + '/jsonp?callback=?';
        $.getJSON(url, function(jsonp){
          $("#jsonp-response").html(JSON.stringify(jsonp, null, 2));
        });
        

        输出:

         {
          "response": "Sent via JSONP",
          "timestamp": "2014-06-18 09:50:15 +0000",
          "random": 364
        }
        

        【讨论】:

          【解决方案7】:

          “JSONP 是带有额外代码的 JSON”对于现实世界来说太容易了。不,你必须有小的差异。如果一切都正常工作,那么编程有什么乐趣?

          原来是JSON is not a subset of JavaScript。如果你所做的只是获取一个 JSON 对象并将其包装在一个函数调用中,那么有一天你会被奇怪的语法错误所困扰,就像我今天一样。

          【讨论】:

            【解决方案8】:

            在从客户端发送来自不同域的 JSON 响应时,JSONP 是一种克服浏览器限制的简单方法。

            但该方法的实际实施涉及到通常无法清楚解释的细微差异。

            这是一个简单的教程,它并排显示 JSON 和 JSONP。

            所有代码都可以在 Github 上免费获得,实时版本可以在 http://json-jsonp-tutorial.craic.com 找到

            【讨论】:

              猜你喜欢
              • 2014-08-12
              • 2011-03-03
              • 2011-10-30
              • 2012-06-06
              • 1970-01-01
              • 2013-06-28
              • 2017-03-01
              • 2018-10-27
              • 2017-01-21
              相关资源
              最近更新 更多