1. 程式人生 > >JavaScript學習-兩種跨域方法

JavaScript學習-兩種跨域方法

第三種方式稱為JSONP,它有個限制,只能用GET請求,並且要求返回JavaScript。這種方式跨域實際上是利用了瀏覽器允許跨域引用JavaScript資源:

<html>
<head>
    <script src="http://example.com/abc.js"></script>
    ...
</head>
<body>
...
</body>
</html>

JSONP通常以函式呼叫的形式返回,例如,返回JavaScript內容如下:

foo('data');

這樣一來,我們如果在頁面中先準備好foo()

函式,然後給頁面動態加一個<script>節點,相當於動態讀取外域的JavaScript資源,最後就等著接收回調了。

refreshPrice({"0000001":{"code": "0000001", ... });

因此我們需要首先在頁面中準備好回撥函式:

function refreshPrice(data) {
    var p = document.getElementById('test-jsonp');
    p.innerHTML = '當前價格:' +
        data['0000001'].name +': ' + 
        data['0000001'].price + ';' +
        data['1399001'].name + ': ' +
        data['1399001'].price;
}

當前價格:

重新整理

最後用getPrice()函式觸發:

function getPrice() {
    var
        js = document.createElement('script'),
        head = document.getElementsByTagName('head')[0];
    js.src = 'http://api.money.126.net/data/feed/0000001,1399001?callback=refreshPrice';
    head.appendChild(js);
}

就完成了跨域載入資料。

CORS

如果瀏覽器支援HTML5,那麼就可以一勞永逸地使用新的跨域策略:CORS了。

CORS全稱Cross-Origin Resource Sharing,是HTML5規範定義的如何跨域訪問資源。

瞭解CORS前,我們先搞明白概念:

Origin表示本域,也就是瀏覽器當前頁面的域。當JavaScript向外域(如sina.com)發起請求後,瀏覽器收到響應後,首先檢查Access-Control-Allow-Origin是否包含本域,如果是,則此次跨域請求成功,如果不是,則請求失敗,JavaScript將無法獲取到響應的任何資料。

用一個圖來表示就是:

js-cors

假設本域是my.com,外域是sina.com,只要響應頭Access-Control-Allow-Originhttp://my.com,或者是*,本次請求就可以成功。

可見,跨域能否成功,取決於對方伺服器是否願意給你設定一個正確的Access-Control-Allow-Origin,決定權始終在對方手中。

上面這種跨域請求,稱之為“簡單請求”。簡單請求包括GET、HEAD和POST(POST的Content-Type型別 僅限application/x-www-form-urlencodedmultipart/form-datatext/plain),並且不能出現任何自定義頭(例如,X-Custom: 12345),通常能滿足90%的需求。

無論你是否需要用JavaScript通過CORS跨域請求資源,你都要了解CORS的原理。最新的瀏覽器全面支援HTML5。在引用外域資源時,除了JavaScript和CSS外,都要驗證CORS。例如,當你引用了某個第三方CDN上的字型檔案時:

/* CSS */
@font-face {
  font-family: 'FontAwesome';
  src: url('http://cdn.com/fonts/fontawesome.ttf') format('truetype');
}

如果該CDN服務商未正確設定Access-Control-Allow-Origin,那麼瀏覽器無法載入字型資源。

對於PUT、DELETE以及其他型別如application/json的POST請求,在傳送AJAX請求之前,瀏覽器會先發送一個OPTIONS請求(稱為preflighted請求)到這個URL上,詢問目標伺服器是否接受:

OPTIONS /path/to/resource HTTP/1.1
Host: bar.com
Origin: http://my.com
Access-Control-Request-Method: POST

伺服器必須響應並明確指出允許的Method:

HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://my.com
Access-Control-Allow-Methods: POST, GET, PUT, OPTIONS
Access-Control-Max-Age: 86400

瀏覽器確認伺服器響應的Access-Control-Allow-Methods頭確實包含將要傳送的AJAX請求的Method,才會繼續傳送AJAX,否則,丟擲一個錯誤。

由於以POSTPUT方式傳送JSON格式的資料在REST中很常見,所以要跨域正確處理POSTPUT請求,伺服器端必須正確響應OPTIONS請求。

轉自