Ajax跨域

發佈自 Kindem的博客,歡迎你們轉載,可是要注意註明出處。另外,該文章收納在 Kindem的我的的 IT 知識整理倉庫,歡迎 Star、Fork、投稿

Ajax跨域簡介

所謂Ajax跨域指的是Ajax請求從其餘的域獲取數據或者傳輸數據html

所謂域同源,指的是兩個服務器資源的根url域名端口協議三者徹底相同,只要三者中任何一個不一樣,則說明產生了跨域前端

給一個例子,對於第一個服務器資源,其餘一些url的同源狀況以下:java

http://www.test.com/index.html

http://www.test.com/index.js            同源
http://www.test.com/login/login.js      同源
https://www.test.com/index.html         跨域(協議)
http://www.a.com/index.html             跨域(域名)
http://a.com/index.html                 跨域(不一樣子域)
http://www.test.com:8080/index.html     跨域(端口)

經常使用跨域方法

CORS

CORS是一個W3C標準,其全稱爲Cross-Origin Resource Sharing,即跨域資源共享。它容許瀏覽器向跨域服務器發送XMLHttpRequest請求,從而克服了Ajax只能同源使用的限制git

CORS須要瀏覽器和服務器同時支持,目前主流瀏覽器都支持這個標準(IE>=10),因此CORS的關鍵主要在於服務器,要支持這個功能,每每開發者須要在服務器端進行額外設置github

另外,CORS標準對用戶來講是透明的,用戶感知不到CORS的存在,一切都是瀏覽器自動完成。當瀏覽器檢測到跨域的Ajax請求時,就會自動作出一些處理,使得請求可以跨域ajax

跨域的Ajax請求分爲兩種:json

  • 簡單請求:跨域

    • 請求方法爲HEADPOSTGET之一
    • HTTP頭字段只有AcceptAccept-LanguageContent-LanguageLast-Event-IDContent-Type中的一種或多種
    • HTTP頭字段中的Content-Type字段的取值爲application/x-www-form-urlencodedmultipart/form-datatext/plain之一
  • 非簡單請求: 全部不知足上述規則的請求

CORS對於兩種不一樣的請求的處理是不一樣的瀏覽器

對於簡單請求,一個跨域Ajax請求的處理流程以下:

  1. 瀏覽器自動在本次請求的HTTP頭中添加Origin字段,表示此次請求來自的域
  2. 服務器根據Origin字段判斷這一次請求是否在許可範圍內:

    • 若是不在,返回一個正常的HTTP響應,只不過響應的HTTP頭中沒有Access-Control-Allow-Origin字段,瀏覽器將認爲這一次跨域Ajax沒能成功
    • 若是在,服務器會在響應HTTP頭中添加這幾個字段

      • Access-Control-Allow-Origin: 這個字段標識服務器認同的Origin,這個Origin*時標識服務器認同全部源。只有請求的HTTP頭的Origin與該字段同源時,瀏覽器纔會認爲這一次跨域Ajax請求成功了
      • Access-Control-Allow-Credentials: 這個字段標識服務器容許Cookie,若是設置爲true則標識容許,默認爲不容許
      • Access-Control-Expose-Headers: 容許XMLHttpRequest獲取的額外字段名

對於非簡單請求,一個跨域Ajax請求的處理流程以下:

  1. 瀏覽器在發送正式的Ajax請求以前,會提早發送一次OPTIONS請求,頭信息中有:

    • Origin: 請求的源
    • Access-Control-Request-Method: 瀏覽器會用的的HTTP方法
    • Access-Control-Request-Headers: 瀏覽器會額外發送的頭信息字段
  2. 收到這個請求以後,服務器將會返回一些控制信息,最重要的仍然是上面說到的斷定是否容許跨域的Access-Control-Allow-Origin
  3. 若是服務器返回了一個正常的HTTP響應,則瀏覽器會認爲OPTIONS請求成功,接下來則會進行真正的的請求
  4. 服務器正常處理真正的請求,而且在返回的HTTP響應中也帶上Access-Control-Allow-Origin,瀏覽器會再一次校驗這一字段

可見CORS標準自己並不複雜,其核心是服務器和瀏覽器驗證域是否被容許

JSONP

JSONP的全稱爲JSON with Padding,是JSON數據的一種使用模式,JSONP一樣是爲了支持跨域Ajax請求而生的,可是它相對CORS來講對古老的瀏覽器兼容性較好,也更加簡單。

JSONP的原理是JavaScript注入,在html中使用<script>標籤引入JavaScript腳本是不會受到同源限制的,這意味着能夠經過<script>標籤引入來自跨域的腳本,像這樣:

// origin:  http://www.test.com

<script>
    function dealData(jsonData) {
        // do something with jsonData
    }
</script>
<script src="http://www.a.com/data.js"></script>

想象一下若是引入的腳本是這樣的:

dealData({
    username: 'kindem',
    age: 15,
    // ...
});

不是就至關於從服務器拿到一段數據而且進行處理了嗎?

接下來能夠設想一下,假設服務器對於src指向的url的處理並非返回一個靜態文件,而是動態地組合出一段文本,這段文本一上面給的形式返回,裏面的參數由服務器動態生成,而調用的函數則是前端約定好的函數,則至關於變相地返回了一段跨域的數據,這就是JSONP的核心思想

相關文章
相關標籤/搜索