JSONP

JSONP 是一種無需考慮跨域問題即可傳送 JSON 數據的方法。

JSONP 不使用 XMLHttpRequest 對象。

JSONP 使用 <script> 標簽取而代之。

JSONP 簡介

JSONP 指的是 JSON with Padding。

從另一個域請求文件會引起問題,由于跨域政策。

從另一個域請求外部腳本沒有這個問題。

JSONP 利用了這個優勢,并使用 script 標簽替代 XMLHttpRequest 對象。

<script src="demo_jsonp.php">

Server 文件

服務器上的文件在函數調用中封裝結果:

實例

<?php
$myJSON = '{ "name":"Bill Gates", "age":62, "city":"Seattle" }';
echo "myFunc(".$myJSON.");";
?>

顯示 PHP 文件

結果返回對名為 "myFunc" 的函數的調用,其中的 JSON 數據為參數。

請確保客戶端存在該函數。

JavaScript 函數

函數 "myFunc" 位于客戶端,用于處理 JSON 數據:

實例

function myFunc(myObj)  {
    document.getElementById("demo").innerHTML =  myObj.name;
}

親自試一試

創建動態腳本標簽

上例會在頁面加載時執行 "myFunc" 函數,根據您放置腳本標簽的位置,這樣不很令人滿意。

Script 只應該在需要時創建:

實例

在按鈕被點擊時創建和插入 <script> 標簽:

function clickButton() {
    var s = document.createElement("script");
    s.src = "demo_jsonp.php";
    document.body.appendChild(s);
}

親自試一試

動態 JSONP 結果

上例仍然是靜態的。

可通過向 PHP 文件發送 JSON 來創建動態的例子,然后根據這個 php 文件獲得的信息讓它返回一個 JSON 對象。

PHP 文件

<?php
header("Content-Type: application/json; charset=UTF-8");
$obj =  json_decode($_GET["x"], false);
$conn = new mysqli("myServer", "myUser", "myPassword", "Northwind");
$result = $conn->query("SELECT name FROM ".$obj->$table." LIMIT ".$obj->$limit);
$outp = array();
$outp = $result->fetch_all(MYSQLI_ASSOC);
echo "myFunc(".json_encode($outp).")";
?>

PHP 文件解釋:

  • 把請求轉換為對象,使用 PHP 函數 json_decode()
  • 訪問數據庫,并用被請求的數據填充數組。
  • 向對象添加數組。
  • 使用 json_decode() 函數把該數組轉換為 JSON。
  • 用 "myFunc()" 封裝返回對象。

JavaScript 實例

將從 php 文件調用 "myFunc" 函數:

function clickButton() {
    var obj, s
    obj = { "table":"products", "limit":10 };
    s =  document.createElement("script");
    s.src = "jsonp_demo_db.php?x="  + JSON.stringify(obj);
    document.body.appendChild(s);
 }
function myFunc(myObj)  {
    var x, txt = "";
    for (x in myObj)  {
        txt += myObj[x].name + "<br>";
     }
    document.getElementById("demo").innerHTML = txt;
}

親自試一試

回調函數

如果您無法控制服務器文件,那么如何使服務器文件調用正確的函數呢?

有時服務器文件提供回調函數作為參數:

實例

PHP 文件會調用您作為回調參數傳遞的函數:

function clickButton() {
    var s = document.createElement("script");
    s.src = "jsonp_demo_db.php?callback=myDisplayFunction";
    document.body.appendChild(s);
}

親自試一試