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將無法獲取到響應的任何資料。
用一個圖來表示就是:
假設本域是my.com
,外域是sina.com
,只要響應頭Access-Control-Allow-Origin
為http://my.com
,或者是*
,本次請求就可以成功。
可見,跨域能否成功,取決於對方伺服器是否願意給你設定一個正確的Access-Control-Allow-Origin
,決定權始終在對方手中。
上面這種跨域請求,稱之為“簡單請求”。簡單請求包括GET、HEAD和POST(POST的Content-Type型別 僅限application/x-www-form-urlencoded
、multipart/form-data
和text/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,否則,丟擲一個錯誤。
由於以POST
、PUT
方式傳送JSON格式的資料在REST中很常見,所以要跨域正確處理POST
和PUT
請求,伺服器端必須正確響應OPTIONS
請求。
轉自