什麼是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;

    ?>
相關文章
相關標籤/搜索