1. 程式人生 > >跨域請求之JSONP 和CORS

跨域請求之JSONP 和CORS

JSONP

JSON with padding ,是一種藉助於script 標籤傳送跨域請求的技巧。
其原理就是在客戶端接住 script 標籤請求服務端的一個動態網頁(PHP檔案),服務端的這個動態網頁返回一段帶有函式呼叫的JavaScript 全域性函式呼叫的指令碼,將原本需要返回給客戶端的資料傳遞進去。
客戶端 https://blog.csdn.net/KleyChan/users-list.html

<script src="https://blog.csdn.net/KleyChan/users.php?callback=foo"></script>

原生程式碼:

<script
>
var script = document.createElement("script"); script.src = "https://blog.csdn.net/KleyChan/users.php"; document.body.appendChild(script); function foo(res){ console.log(res) } </script>

封裝函式程式碼:

<script>
     function jsonp(url, params, callback)
{
if (typeof params === 'object') { var temArr = []; for(var key in params){ var value = params[key]; temArr.push (key + '=' + value); } params = temArr.join('&'); } var script = document.createElement("script"
); // 申明一個變數函式名,保證每次請求的callback函式名不一樣 var fun_name = 'jsonp_' + Date.now() +Math.random().toString().substr(2, 5); script.src = url+ '?'+ params + "&callback=" +fun_name; document.body.appendChild(script); window[fun_name] = function (res){ callback(res); // 每次用完 刪除函式,刪除標籤 // 為什麼函式也要刪除?? 全域性函式,避免汙染 delete window[fun_name]; document.body.removeChild(script); } }
</script> // 函式呼叫 jsonp ('https://blog.csdn.net/KleyChan/users.php', {id: 1111},function(res){ console.log(res); })

jQuery 也把jsonp封裝成函式:

<script>
        // 這個其實跟ajax 沒有任何關係
        $.ajax({
          url: 'https://blog.csdn.net/KleyChan/users.php',
          data: {id:11111},
           // 區別就是dataType: 'jsonp'
          dataType: 'jsonp',
          success: function(res){
            console.log(res);
          }
        })
    </script>
foo(['我','是','資料'])

總結:
由於XMLHttpRequest 無法傳送不同源地址之間的跨域請求,所以我們必須要另尋他法,script 這種方案就是我們最終選擇的方式,我們把這種方式稱之為JSONP ,如果你不瞭解原路,先記住怎麼用,多用一段時間再來看原理。
問題:
1. JSONP 需要服務端的配合,服務端按照客服端的要求返回一段JavaScript 呼叫客戶端的函式
2. 只能傳送GET 請求
3. 注意JSONP 用的是script 標籤,跟AJAX 提供的XMLHttpRequest 沒有任何關係!!!

jQuery 中使用JSONP 就是將dataType 設定為jsonp。

CORS

Cross Origin Resource Share, 跨域資源共享

它允許瀏覽器向跨源伺服器,發出XMLHttpRequest請求,從而克服了AJAX只能同源使用的限制。 CORS需要瀏覽器和伺服器同時支援。目前,所有瀏覽器都支援該功能,IE瀏覽器不能低於IE10。 整個CORS通訊過程,都是瀏覽器自動完成,不需要使用者參與。對於開發者來說,CORS通訊與同源的AJAX通訊沒有差別,程式碼完全一樣。瀏覽器一旦發現AJAX請求跨源,就會自動新增一些附加的頭資訊,有時還會多出一次附加的請求,但使用者不會有感覺。
因此,實現CORS通訊的關鍵是伺服器。只要伺服器實現了CORS介面,就可以跨源通訊。

在php中,通過下面程式碼給客戶端設定一個響應頭,瀏覽器響應時就會知道允許跨域了

// 允許所有網站跨域訪問該網站
header('Access-Control-Allow-Origin: *')
//只允許某個地址(百度


)跨域訪問該網站
header( 'Access-Control-Allow-Origin:http://baidu.com' )

這種方案無需客戶端做出任何變化(客戶端不用改程式碼),只是在被請求的服務端響應的時候新增一個Access-Control-Allow-Origin 的響應頭,表示這個資源是否允許指定域請求。

jsonp方式和cors方式的區別

  • jsonp是jquery提供的跨域方式
  • cors是w3c提供的一個跨域標準

——————————————————————

  • jsonp只支援get方式的跨域
  • cors支援get和post方式的跨域

——————————————————————

  • jsonp支援所有的瀏覽器(因為所有瀏覽器都可以使用script標籤傳送請求)
  • cors不支援IE10以下的瀏覽器

儘管這兩種跨域方法可以解決跨域的問題,但兩者的缺點都是非常依賴服務端的操作。