1. 程式人生 > 其它 >ajax跨域有沒有踩過坑,IE低版本瀏覽器如何支援?

ajax跨域有沒有踩過坑,IE低版本瀏覽器如何支援?

同源策略

為了保證使用者資訊的安全,防止惡意的網站竊取資料,所有的瀏覽器都實行這個策略。

同源策略是指,使用者在A網頁上的所產生的資訊,B網頁上不能訪問,反過來A網頁也不能訪問其它網頁的資訊,除非這兩個網頁"同源"。

為什麼說同源策略可以保證使用者資訊保安,舉個栗子:A網站是一家銀行,使用者登入以後,又去瀏覽其他網站。如果其他網站可以讀取A網站的 Cookie,會發生什麼?

兩個文件同源需滿足

1. 協議相同

2. 域名相同

3. 埠相同

Ajax跨域通訊

同源策略規定,Ajax請求只能發給同源的網址,否則就報錯。然而我們開發過程中常常會碰到需要請求不同伺服器上的資料。那麼Ajax跨域通訊就必須要解決了。

三種方式:

  • JSONP:JSONP是伺服器與客戶端跨源通訊的常用方法,網頁通過新增一個<script>元素,向伺服器請求JSON資料,這種做法不受同源政策限制;伺服器收到請求後,將資料放在一個指定名字的回撥函式裡傳回來。可惜只能是傳送 get 請求
  • WebSocket:WebSocket是一種通訊協議,使用ws://(非加密)和wss://(加密)作為協議字首。該協議不實行同源政策,只要伺服器支援,就可以通過它進行跨源通訊。(基本上不用此種方式,學習成本比較高)
  • CORS:CORS是跨源資源分享(Cross-Origin Resource Sharing)的縮寫。它是W3C標準,是跨源AJAX請求的根本解決方法。CORS需要瀏覽器和伺服器同時支援。目前,所有瀏覽器都支援該功能,IE瀏覽器不能低於IE10

CORS

  1. ie瀏覽器版不能低於IE10
  2. 後臺伺服器指令碼需要明白的一些請求頭:

Access-Control-Allow-Origin:允許哪些url可以跨域請求到本域,Access-Control-Allow-Origin:* 表示所有url都可以請求到本域名,如果你很懶可以這樣寫

Access-Control-Allow-Methods:允許的請求方法,一般是GET,POST,PUT,DELETE,OPTIONS

Access-Control-Max-Age:表明在該時間段內不再“預檢”允許的請求方法(相當於快取),即不以OPTIONS方法進行請求

Access-Control-Allow-Headers:允許哪些請求頭可以跨域

CORS Python伺服器請求頭示例:

你將以下程式碼放到你的php程式碼的頭部,咱們就可以實現ajax跨域請求了

response = HttpResponse(json.dumps({"key": "value", "key2": "value"})) response["Access-Control-Allow-Origin"] = "*" response["Access-Control-Allow-Methods"] = "POST, GET, OPTIONS" response["Access-Control-Max-Age"] = "1000" response["Access-Control-Allow-Headers"] = "*"

IE10以上版本,都好辦,問題是有些使用者就用了IE7,8該怎麼辦?當然,首先是鄙視一下這部分使用者,鄙視完了,還是要想辦法解決問題,畢竟做產品還是要以使用者為上~

網上查了一圈,發現IE7 和以前是不支援跨域請求的, IE8 通過 XMLDocumentRequest實現,而不是 XMLHTTPRequest,所以IE8下面應該這樣寫:

// 建立XHR物件
function createCORSRequest(method, url) {
    var xhr = new XMLHttpRequest();
    if ("withCredentials" in xhr) {
        // 針對Chrome/Safari/Firefox.
        xhr.open(method, url, true);
    } else if (typeof XDomainRequest != "undefined") {
        // 針對IE
        xhr = new XDomainRequest();
        xhr.open(method, url);
    } else {
        // 不支援CORS
        xhr = null;
    }
    return xhr;
}

// 傳送CORS請求
function makeCorsRequest(method, url, cb) {
    // bibliographica.org是支援CORS的
    var xhr = createCORSRequest(method, url);
    if (!xhr) {
        alert('CORS not supported');
        return;
    }

    // 迴應處理
    xhr.onload = function () {
        var text = xhr.responseText;
        text = $.parseJSON(text);
        cb(text);
    };

    xhr.onerror = function () {
        alert('Woops, there was an error making the request.');
    };
    xhr.send();
}

拉下來,我們就區分一下瀏覽器,如果是IE10以下版本,那就直接另一種方式,呼叫上面的實現方式。