1. 程式人生 > >前端跨域解決方法總結

前端跨域解決方法總結

同源策略:
所謂同源策略,指的是瀏覽器對不同源的指令碼或者文字的訪問方式進行的限制。
同源:協議相同,域名相同,埠相同。
同源策略主要帶來三個方面的行為限制:
1、cookie,localstorage和IndexDB無法讀取
2、DOM無法獲取
3、Ajax請求不能傳送規避方法:

跨域方法總結
1、JSONP
優點:簡單易用,瀏覽器支援好。
缺點:
1. JSONP是從其他域中載入程式碼並執行,所以存在很多安全隱患,如果其他伺服器在響應中夾帶惡意程式碼的話,沒有辦法防範。
2. JSONP難以確定請求失敗的情況。HTML5中給<script>元素增加了一個onerror事件,但是還是有瀏覽器不支援。
3. 只能傳送GET請求

2、影象Ping:
一個網頁可以從任何網頁中載入影象。影象ping這是指通過請求圖片的方式來跨域傳送請求。動態建立影象經常用於影象 Ping。影象 Ping 是與伺服器進行簡單、單向的跨域通訊的一種方式。 請求的資料是通過查詢字串形式傳送的,而響應可以是任意內容,但通常是畫素圖或 204響應。通過 影象 Ping,瀏覽器得不到任何具體的資料,但通過偵聽 load 和 error 事件,它能知道響應是什麼時 候接收到的。中傳送了一個 name 引數。 影象 Ping常用於跟蹤使用者點選頁面或動態廣告曝光次數。
優點:簡單,相容性好,不需要伺服器做針對性處理。
缺點:
1. 只能單向通訊,即客戶端傳送訊號給服務端,無法接收到服務端的回覆
2. 只能傳送GET請求
3. 容易被瀏覽器快取請求,導致請求傳送不出去。

var img = new Image();
img.onload = img.onerror = function () {
    alert("Done!");
};
img.src = "http://www.example.com/test?name=Nicholas";

3、CORS
CORS是Cross-Origin Resource Sharing的縮寫,即跨域資源共享。CORS的基本思想就是使用自定義的HTTP頭部讓瀏覽器與伺服器進行溝通,從而決定請求或響應是應該成功,還是應該失敗。
例子:比如一個簡單的使用 GET 或 POST 傳送的請求,它沒有自定義的頭部,而主體內容是 text/plain。在 傳送該請求時,需要給它附加一個額外的 Origin 頭部,其中包含請求頁面的源資訊(協議、域名和端 口),以便伺服器根據這個頭部資訊來決定是否給予響應。下面是 Origin 頭部的一個示例:Origin:

http://www.nczonline.net。如果伺服器認為這個請求可以接受,就在 Access-Control-Allow-Origin 頭部中回發相同的源資訊(如果是公共資源,可以回發”*”)。例如:Access-Control-Allow-Origin: http://www.nczonline.net。如果沒有這個頭部,或者有這個頭部但源資訊不匹配,瀏覽器就會駁回請求。正常情況下,瀏覽器會處理請求。注意,請求和響應都不包含 cookie資訊。
優點:功能強大
缺點:
1. 需要服務端來配合實現
2. IE必須IE10以上。。。

function createCORSRequest(method,url){
    var xhr=new XMLHttpRequest();
    if("withCredentials" in xhr){
        xhr.open(method,url,true);
    }else if(typeof XDomainRequest !="undefined"){
        xhr=new XDomainRequest();
        xhr.open(method,url);
    }else{
        xhr=null;
    }
    return xhr;
}

4、WebSocket
優點:
1. 雙工通訊,瀏覽器和伺服器都可以發起請求
2. 通訊效率高,一次連結可以複用,省去反覆的握手環節
缺點:
1. 實現上較為複雜,包括客戶端和服務端
2. 瀏覽器支援問題
Web Sockets的目標是在一個單獨的 持久連線上提供全雙工、雙向通訊。在 JavaScript中建立了 Web Socket之後,會有一個 HTTP請求傳送到瀏覽器以發起連線。在取得伺服器響應後,建立的連線會使用 HTTP 升級從 HTTP 協議交換為 Web Socket 協議。也就是說,使用標準的 HTTP 伺服器無法實現 Web Sockets,只有支援這種協議的專門服 務器才能正常工作。 由於 Web Sockets使用了自定義的協議,所以 URL模式也略有不同。未加密的連線不再是 http://, 而是 ws://;加密的連線也不是 https://,而是 wss://。在使用 Web Socket URL時,必須帶著這個 模式,因為將來還有可能支援其他模式。
使用自定義協議而非 HTTP協議的好處是,能夠在客戶端和伺服器之間傳送非常少量的資料,而不 必擔心 HTTP那樣位元組級的開銷。由於傳遞的資料包很小,因此 Web Sockets非常適合移動應用。

6、Comet
Comet指的是一種更高階的 Ajax技術(經常也有人稱為“伺服器 推送”)。Ajax 是一種從頁面向伺服器請求資料的技術,而 Comet 則是一種伺服器向頁面推送資料的技 術。Comet能夠讓資訊近乎實時地被推送到頁面上,非常適合處理體育比賽的分數和股票報價。
有兩種實現 Comet的方式:長輪詢和流。
長輪詢是傳統輪詢(也稱為短輪詢)的一個翻版,即瀏覽器定時向伺服器傳送請求,看有沒有更新的資料。長輪詢把短輪詢顛倒了一下。頁面發起一個到伺服器的請求,然後伺服器一直保持連線開啟,直到有資料可傳送。傳送完資料之後,瀏覽器關閉連線,隨即又發起一個到伺服器的新請求。這一過程在頁 面開啟期間一直持續不斷。無論是短輪詢還是長輪詢,瀏覽器都要在接收資料之前,先發起對伺服器的連線。兩者大的區別 在於伺服器如何傳送資料。短輪詢是伺服器立即傳送響應,無論資料是否有效,而長輪詢是等待發送響 應。輪詢的優勢是所有瀏覽器都支援,因為使用 XHR物件和 setTimeout()就能實現。而你要做的就是決定什麼時候傳送請求。
第二種流行的 Comet實現是 HTTP流。流不同於上述兩種輪詢,因為它在頁面的整個生命週期內只 使用一個 HTTP連線。具體來說,就是瀏覽器向伺服器傳送一個請求,而伺服器保持連線開啟,然後週期性地向瀏覽器傳送資料。所有伺服器端語言都支援列印到輸出快取然後重新整理(將輸出快取中的內容一次性全部發送到客戶 端)的功能。而這正是實現 HTTP流的關鍵所在。 在 Firefox、Safari、Opera和 Chrome中,通過偵聽 readystatechange 事件及檢測 readyState 的值是否為 3,就可以利用 XHR 物件實現 HTTP 流。在上述這些瀏覽器中,隨著不斷從伺服器接收數 據,readyState 的值會週期性地變為 3。當 readyState 值變為 3時,responseText 屬性中就會保 存接收到的所有資料。此時,就需要比較此前接收到的資料,決定從什麼位置開始取得新的資料。使 用 XHR物件實現 HTTP流的典型程式碼如下所示。

function createStreamingClient(url, progress, finished) {
    var xhr = new XMLHttpRequest(), received = 0;
    xhr.open("get", url, true);
    xhr.onreadystatechange = function () {
        var result;
        if (xhr.readyState == 3) {
            //只取得最新資料並調整計數器            
            result = xhr.responseText.substring(received);             
            received += result.length;
            //呼叫 progress 回撥函式             
            progress(result);
        } else if (xhr.readyState == 4) {
            finished(xhr.responseText);
        }
    };
    xhr.send(null);
    return xhr;
}

var client = createStreamingClient("streaming.php", function (data) {
    alert("Received: " + data);

}, function (data) {
    alert("Done!");
});

7、伺服器傳送事件
SSE(Server-Sent Events,伺服器傳送事件)是圍繞只讀 Comet互動推出的 API或者模式。SSE API 用於建立到伺服器的單向連線,伺服器通過這個連線可以傳送任意數量的資料。伺服器響應的 MIME 型別必須是 text/event-stream,而且是瀏覽器中的 JavaScript API 能解析格式輸出。SSE 支援短輪 詢、長輪詢和 HTTP流,而且能在斷開連線時自動確定何時重新連線。有了這麼簡單實用的 API,再實 現 Comet就容易多了。

**注意:**SSE與Web Sockets 面對某個具體的用例,在考慮是使用 SSE還是使用 Web Sockets時,可以考慮如下幾個因素。
首先, 你是否有自由度建立和維護 Web Sockets伺服器?因為 Web Socket協議不同於 HTTP,所以現有伺服器 不能用於 Web Socket通訊。SSE倒是通過常規 HTTP通訊,因此現有伺服器就可以滿足需求。
第二個要考慮的問題是到底需不需要雙向通訊。如果用例只需讀取伺服器資料(如比賽成績),那 麼 SSE 比較容易實現。如果用例必須雙向通訊(如聊天室),那麼 Web Sockets 顯然更好。別忘了,在 不能選擇 Web Sockets的情況下,組合 XHR和 SSE也是能實現雙向通訊的。