【javascript】 藉助script元素髮送HTTP請求:JSONP原理-2

   在完成上次簡單的測試之後,接下來將結合《javascript權威指南》關於jsonP例子,介紹如何動態請求和響應數據. 首先,我們需要編寫一個客戶端頁面,通過綁定事件的方式,向指定地址發送jsonP請求。

   服務端1: Node .  URL : http://localhost:3000

   服務端2: Nginx+PHP  . URL : http://localhost:8080

   同一主機,不同端口符合同源策略。

  首先我們現在設置服務端2的頁面,主要是產生一個可視化文檔,填寫參數向目的地發送請求。

 
test.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>jsonP</title>
    <script>
        var getJSONP = { counter : 0};  // 管理jsonP請求次數 和 函數
        function  sendRequest(){
            var q =  document.getElementsByName("qname")[0].value;  //取得 文本框數據
            var url  = "http://localhost:3000";  //設置爲 node 服務端 地址
            if(typeof q !="undefined"){
                url+="?q="+q;   //附加參數
            }
            createJsonP(url,function(res){   //開始執行jsonP函數     
                console.log(res);   

            });
        }

        function  createJsonP(url,callback){   // 發送請求 url   和  回調函數
            console.log("start");
            var cbnum = "cb" + getJSONP.counter++ ;   // 每一次jsonP請求 都會進行統計 自增
            var cbname = "getJSONP." +cbnum; // callback 回調函數唯一名稱

            if(url.indexOf("?")==-1){
                url+="?jsonp=" + cbname;     //這裏的jsonp 鍵名是一個關鍵字,將與服務端1獲取get請求參數名一致。而鍵值則是請求成功後調用的函數名稱
            }else{
                url+="&jsonp=" + cbname;
            }
            var script =  document.createElement("script");   // 創建一個script 元素
            // 預先設置好 回調函數
            getJSONP[cbnum]  = function (res){     //設置script 元素的 src 之前 聲明好 回調函數.
                try{
                    console.log(getJSONP);   
                    callback(res); //   執行真正的 回調函數.
                }finally{
                    //  執行完回調函數後 刪除輔助的回調函數 和 剛剛添加的script元素
                    delete getJSONP[cbnum];
                    script.parentNode.removeChild(script);
                }
            };
            // 設置 請求地址 此時纔開始進行ajax請求 腳本 
            script.src = url;
            document.documentElement.appendChild(script);  //添加到 文檔裏面
        }
    </script>
</head>

<body>
    <label for="">qname:</label>
    <input type="text" id ="val" name="qname">
    <button id="btn">開始請求</button>
</body>
<script>
        window.onload = function (){
           var btn =  document.getElementById('btn');
           btn.addEventListener("click",sendRequest,false);
        }
</script>
</html>

   接下來是Node環境裏處理該請求,實際上使用任何服務端腳本語言都可以,只要將返回的格式爲 callbak( json格式參數 ), 客戶端腳本就會執行 callback方法。

var express = require('express');

// 建立 express 實例
var app = express();
app.get('/', function (req, res) {  // 監聽根目錄
      var data = { name:"abc",type:"jsonP" , q : req.query.q };
      var str = req.query.jsonp + '(' + JSON.stringify(data) + ')';//jsonp 是一個關鍵名  req.query.jsonp 就是獲取客戶端傳遞過來的 get請求中的jsonp鍵值
    
      if(typeof req.query.q !="undefined"){
         console.log("request q is "+str);
      }
      res.send(str);    //返回符合格式的字符串
});

app.listen(3000, function (req, res) {
  console.log('app is running at port 3000');
});

   接下啦.我們進行一次測驗.首先查看客戶端頁面

 

   我們在文本框填寫數據後,點擊按鈕.進行發送.這是會發送一個如下的get請求

  可以看到getJSONP.cb0是我們第一次的回調函數名稱. 而getJSONP 對象的格式如下:

  產生立一個cb0的屬性,屬性類型爲函數類型.

  服務端1 在終端輸出的內容爲:

  

   說明確實有請求進行訪問.同時返回的格式爲: getJSONOP.cb0({});  這樣 當客戶端請求成功後 , 會執行getJSONP 對象裏的cb0函數。執行的結果就是調用真正的callback函數,將數據傳遞給callback函數.同時銷燬 getJSONP 對象的 cb0函數,

  真正的callback函數 就會將我們的json 數據打印在客戶端控制檯中。

  這樣,一個動態的設置參數請求jsonP的例子就介紹完了。實際上本身就是利用了script 元素可以引用外部任何javascript格式的腳本. 支持跨域,跨服務器.避免了同源策略的產生.

  關於如何避免同源策略的問題,我們還得需要通過更多的例子進行介紹.


發佈了31 篇原創文章 · 獲贊 6 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章