什么是JSONP,为何建立它?

我了解JSON,但不了解JSONP。 Wikipedia上有关JSON的文档是JSONP的最高搜索结果。 它说: javascript

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

?? 什么电话 这对我来讲毫无心义。 JSON是一种数据格式。 没有电话 html

第二个搜索结果来自一个叫Remy的人 ,他写了关于JSONP的代码: java

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

我能够理解,但这仍然没有任何意义。 api


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


附录 :我刚刚在Wikipedia 上为JSONP建立了一个新页面 。 根据jvenema的回答,它如今对JSONP有了清晰而透彻的描述。 浏览器


#1楼

JSONP经过构造一个“脚本”元素(以HTML标记或经过JavaScript插入DOM)来工做,该元素请求到远程数据服务位置。 响应是使用预约义函数名称以及所传递的参数(即请求的JSON数据)加载到浏览器上的JavaScript。 执行脚本时,该函数将与JSON数据一块儿调用,从而容许请求页面接收和处理数据。 安全

有关进一步的阅读访问, 访问: https : //blogs.sap.com/2013/07/15/secret-behind-jsonp/ 服务器

客户端代码段

<!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>

服务器端的一段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 . ")";
?>

#2楼

JSONP能够很好地解决跨域脚本错误。 您能够只使用JS来使用JSONP服务,而没必要在服务器端实现AJAX代理。

您可使用b1t.co服务查看其工做方式。 这是一项免费的JSONP服务,可以让您缩小URL。 这是用于服务的网址:

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

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

会回来

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

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

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

要真正进行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);
}

这篇文章提供了一个分步示例和一个jsonp Web服务进行练习:


#3楼

由于您能够要求服务器将前缀附加到返回的JSON对象。 例如

function_prefix(json_object);

为了使浏览器eval “内联” JSON字符串做为表达式。 此技巧使服务器能够直接在客户端浏览器中“注入” javascript代码,而且绕过了“相同来源”限制。

换句话说,您能够进行跨域数据交换


一般, XMLHttpRequest不容许直接进行跨域数据交换(须要经过同一域中的服务器),而:

<script src="some_other_domain/some_data.js&prefix=function_prefix >`人们能够从不一样于来源的域访问数据。


一样值得注意的是:即便在尝试这种“技巧”以前,应将服务器视为“受信任的”服务器,也能够包含对象格式等可能发生变化的反作用。 若是使用function_prefix (即适当的js函数)来接收JSON对象,则该函数能够在接受/进一步处理返回的数据以前执行检查。


#4楼

实际上并不太复杂...

假设您使用的是example.com域,而且想向example.net域发出请求。 要作到这一点,你须要跨域边界, 无无多数browserland的。

绕过此限制的一项是<script>标记。 使用脚本标记时,将忽略域限制,可是在正常状况下,您实际上没法对结果任何事情,只是对脚本进行了评估。

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

例如,假设服务器须要一个名为callback的参数来启用其JSONP功能。 而后您的请求将以下所示:

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

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

{ foo: 'bar' }

可是,使用JSONP时,服务器收到“ callback”参数时,其包装结果会有所不一样,返回以下所示:

mycallback({ foo: 'bar' });

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

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

如今,加载脚本后,将对其进行评估,而后将执行您的函数。 瞧,跨网域要求!

值得注意的是JSONP的一个主要问题:您失去了对请求的大量控制。 例如,没有“不错”的方法来找回正确的故障代码。 结果,您最终会使用计时器来监视请求等,这老是让人怀疑。 JSONRequest的主张是一个很好的解决方案,它容许跨域脚本编写,维护安全性并容许对请求的适当控制。

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


#5楼

一个使用JSONP的简单示例。

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

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

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

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

    ?>
相关文章
相关标签/搜索