javascript - jsonp跨域 - php jsonp




什麼是JSONP? (5)

這個問題在這裡已經有了答案:

我了解JSON,但不了解JSONP。 關於JSON的Wikipedia文檔是(是)JSONP的最高搜索結果。 它說:

JSONP或“帶填充的JSON”是JSON擴展,其中前綴被指定為調用本身的輸入參數。

咦? 什麼呼叫? 這對我來說沒有任何意義。 JSON是一種數據格式。 沒有電話。

第二個搜索結果來自一位Remy ,他寫了關於JSONP的文章:

JSONP是腳本標記註入,將來自服務器的響應傳遞給用戶指定的函數。

我可以理解,但它仍然沒有任何意義。

那麼什麼是JSONP? 它為什麼被創建(它解決了什麼問題)? 為什麼我會使用它?

附錄 :我剛剛在Wikipedia 上為JSONP創建了一個新頁面 ; 它基於jvenema的回答,現在對JSONP有了一個清晰而全面的描述。


JSONP很適合解決跨域腳本錯誤。 您可以純粹使用JS來使用JSONP服務,而無需在服務器端實現AJAX代理。

您可以使用b1t.co服務查看它的工作原理。 這是一項免費的JSONP服務,可以讓您縮減您的網址。 以下是用於該服務的網址:

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網絡服務


JSONP通過構建一個“script”元素(HTML標記或通過JavaScript插入到DOM中)來工作,該元素請求遠程數據服務位置。 響應是一個JavaScript加載到您的瀏覽器與預定義的函數的名稱以及被傳遞的參數,即請求的JSON數據。 當腳本執行時,該函數與JSON數據一起被調用,允許請求頁面接收和處理數據。

進一步閱讀訪問: https://blogs.sap.com/2013/07/15/secret-behind-jsonp/ 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 . ")";
?>

一個使用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;

    ?>    

其實並不復雜......

假設你在域example.com上,並且你想向域example.net發出請求。 要做到這一點,你需要跨越領域的界限,在大多數瀏覽器領域都是不允許的。

繞過這個限制的一個條目是<script>標籤。 當您使用腳本標記時,域限制將被忽略,但在正常情況下,您無法對結果進行任何操作,只會對腳本進行評估。

輸入JSONP。 當您向啟用了JSONP的服務器發出請求時,您會傳遞一個特殊參數,告訴服務器關於您的頁面的一些信息。 這樣,服務器就可以很好地將其響應以您的頁面可以處理的方式包裝起來。

例如,假設服務器需要一個名為“callback”的參數來啟用其JSONP功能。 然後您的請求將如下所示:

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

沒有JSONP,這可能會返回一些基本的JavaScript對象,如下所示:

{ foo: 'bar' }

但是,使用JSONP時,當服務器收到“回調”參數時,它將結果稍微區別開來,返回如下所示的內容:

mycallback({ foo: 'bar' });

正如你所看到的,它現在將調用你指定的方法。 所以,在你的頁面中,你定義了回調函數:

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

現在,當腳本被加載時,它將被評估,並且你的函數將被執行。 Voila,跨域請求!

同樣值得注意的是JSONP的一個主要問題:您失去了對請求的很多控制。 例如,沒有“好”的方法來獲取適當的失敗代碼。 結果,你最終使用定時器來監視請求等,這總是有點可疑。 JSONRequest的提議是允許跨域腳本編寫,維護安全性並允許正確控制請求的一個很好的解決方案。

現在(2015年), CORS是推薦的方法與JSONRequest。 JSONP對於較老的瀏覽器支持仍然有用,但考慮到安全隱患,除非您沒有選擇,否則CORS是更好的選擇。


在理解JSONP之前,您需要了解JSON格式和XML。 目前Web上最常用的數據格式是XML,但XML非常複雜。 它使用戶不便處理嵌入在網頁中的內容。

為了使JavaScript能夠輕鬆地交換數據,即使作為數據處理程序,我們也根據JavaScript對象使用了措辭並開發了一種簡單的數據交換格式,即JSON。 JSON可以用作數據,也可以用作JavaScript程序。

JSON可以直接嵌入到JavaScript中,使用它們可以直接執行某些JSON程序,但由於安全限制,瀏覽器Sandbox機制會禁用跨域JSON代碼執行。

為了使JSON可以在執行後傳遞,我們開發了一個JSONP。 JSONP利用JavaScript回調函數和<script>標記繞過瀏覽器的安全限制。

總之,它解釋了什麼是JSONP,它解決了什麼問題(何時使用它)。





terminology