JSONP跨域請求入門教學(附帶範例)

2020-07-16 10:05:09
JSONP (JSON with Padding)是在用戶端生成 <script> 標籤來呼叫跨域指令碼(伺服器端指令碼檔案)的一個非官方協定。JSONP 允許在伺服器端動態生成 JavaScript 字串返回給用戶端,通過 JavaScript 回撥函數的形式實現跨域呼叫。

範例1

現在很多 JavaScript 技術框架都使用 JSONP 實現跨域非同步通訊,如 dojo、jQuery、Youtobe、GData API、Google Social Graph API、Digg API 等。 範例1 下面範例演示了如何使用 script 實現非同步 JSON 通訊。

1) 在伺服器端的 JavaScript 檔案中輸入下面程式碼(server.js).
callback({
    "title" : "JSONP Test",
    "link" : "http://www.mysite.cn/",
    "modified" : "2016-12-1",
    "items" : [{
        "title" : "百度",
        "link" : "http://www.baidu.com/",
    "description" : "百度側重於中國網友的搜尋習慣,搜尋結果更加大眾化。"
    },{
    "title" : "谷歌",
    "link" : "http://www.google.cn/",
    "description" : "谷歌搜尋結果更客觀,尤其在搜尋技術性文章的時候,結果更加精準。"
    }]
})
callback 是回撥函數的名稱,使用小括號運算子呼叫該函數,並傳遞一個 JavaScript 物件。在這個物件中包含 4 個屬性:title、link、modified、items。其中前 3 個屬性值是字串,第 4 個屬性 items 包含一個陣列,陣列中包含兩個物件。這兩個物件又包含兩個屬性:title、link。

通過這種方式可以在一個 JavaScript 物件中包含更多資訊,在用戶端的 <script> 標籤中可以利用 src 屬性把伺服器端的這些 JavaScript 指令碼作為響應資訊引入到用戶端的 <script> 標籤中。

2) 在回撥函數中逐層遍歷和分解 JSON 資料,有序顯示所有響應資訊(test.html)。
function callback(info){
    var temp = "";
    for(var i in info){
        if(typeof info[i] != "object"){
            temp += i + " = "" + info[i] + ""<br />";
     }else if( (typeof info[i] == "object") && (info[i].constructor == Array)){
        temp += "<br />" + i + " = " + "<br /><br />";
        var a = info[i];
        for(var j = 0; j < a.length; j ++ ){
            var o = a[j];
           for(var e in o){
               temp += "&nbsp;&nbsp;&nbsp;&nbsp;" + e + " = "" + o[e] + ""<br />";
            }
             temp +=  "<br />";
            }
        }
    }
    var div  = document.getElementById("test");
    div.innerHTML = temp;
}

3) 完成使用者提交資訊的操作。用戶端提交頁面(test.html)的程式碼如下:
function request(url){
    if( ! document.script){
        document.script = document.createElement("script");
        document.script.setAttribute("type", "text/javascript");
        document.script.setAttribute("src", url);
        document.body.appendChild(document.script);
    } else {
        document.script.setAttribute("src", url);
    }
}
window.onload = function(){
    var b = document.getElementsByTagName("input")[0];
    b.onclick = function(){
        var url = "server.js"
        request(url);
    }
}
<h1>用戶端資訊提交頁面</h1>
<input name="submit" type="button" id="submit" value="向伺服器發出請求" />
<div id="test"></div>
回撥函數和請求函數的名稱並不是固定的,使用者可以自定義這些函數的名稱。

4) 儲存頁面,在瀏覽器中預覽,演示效果如下圖所示。