跨域之CORS

查小小飛發表於2019-09-22

沒有後端,你咋跨域。。

CORS是幹啥的

CORS全稱是:Cross-Origin Resource Sharing,跨域資源共享。是解決AJAX跨域的一種方案。正常情況下,AJAX 發起跨域請求後,瀏覽器拒絕接收響應,會報跨域的錯。CORS是W3C的一個標準,他新增了一些機制,可以使得瀏覽器能夠接收跨域的響應。雖然JSONP能夠實現跨域,但它不夠正統,存在一些缺陷,JSONP只支援GET請求,這就需要一種更加正統的方法,而不是像JSONP一樣利用了<script>標籤可以載入跨域JS的特性來實現跨域,這樣的法更像是曲線救國。那麼有可不可以從本質上實現跨域訪問呢,並且不侷限於GET請求,這就是CORS。

小結: CORS是實現AJAX跨域的一種方案。

如何實現CORS

先知道怎麼用,再搞懂原理。實現CORS很簡單,前端的AJAX程式碼不需要任何改動,只需要後端設定一下響應頭的 Access-Control-Allow-Origin欄位就能夠實現跨域訪問。將Access-Control-Allow-Origin的值設定成請求方的域名即可,當然也可以設定成*,即表示,任何域名的請求都可以訪問。例:請求方域名是 http://www.a.com,假設我需要向 http://www.b.com發介面請求。那麼服務需要響應端設定響應頭Access-Control-Allow-Origin: http://www.a.com。這樣就能夠順利請求了。

小結: 後端設定響應頭的 Access-Control-Allow-Origin 欄位。

CORS的本質

同源策略的本質

首先,你要搞清楚,是同源策略導致了跨域問題。根本原因是瀏覽器做了限制,瀏覽器不讓你從別的地方去請求資料,即使請求發出去了,瀏覽器也不會接受的響應的,這是一種安全策略。

CORS的本質

如何使得瀏覽器接受跨域的響應呢?這就得讓瀏覽器知道,噢,這個響應是安全的,是可以接收的。那麼瀏覽器又通過什麼東西知道響應是安全的,是能夠接收的呢?當然是響應頭了。那麼只需要在響應頭裡告訴瀏覽器,這個響應是沒問題的,你接收吧。那麼究竟怎麼做呢,具體是如何在響應頭裡進行相關設定呢,這就是CORS規定的,這就是CORS標準。

跨域資源共享標準新增了一組HTTP首部欄位,允許伺服器宣告哪些源站通過瀏覽器有許可權訪問哪些資源。這些HTTP頭決定瀏覽器是否阻止前端 JavaScript 程式碼獲取跨域請求的響應。CORS定義了在訪問跨源資源時,瀏覽器與伺服器應該如何溝通。CORS 背後的基本思想,就是使用自定義的HTTP頭部,讓瀏覽器與伺服器進行溝通,從而決定請求或響應是應該成功,還是應該失敗。

小結: CORS的本質是通過HTTP響應頭告訴瀏覽器,響應是安全的,可以接收的。

IE中的CORS

對於IE10以下,CORS的實現並不是在XMLHTTPRequest物件上實現的(IE支援XHR物件,只是CORS不是在XHR物件上實現的),對於IE10 - ,CORS是在IE獨有的 XDomainRequest (XDR) 上實現的,這個物件和XHR一樣,用法和功能幾乎一樣。

XDR的用法:

if(window.XDomainRequest){
  var xdr = new XDomainRequest();
  xdr.open("get", "http://example.com/api/method");
  xdr.onprogress = function () {
    //Progress
  };
  xdr.ontimeout = function () { 
    //Timeout
  };
  xdr.onerror = function () { 
    //Error Occured
  };
  xdr.onload = function() {
    //success(xdr.responseText);
  }
  setTimeout(function () {
    xdr.send();
  }, 0);
}
複製程式碼

XDR的用法基本和XHR一樣,有些細微的地方需要注意:

  • cookie 不會隨請求傳送,也不會隨響應返回。
  • 只能設定請求頭部資訊中的 Content-Type 欄位。
  • 不能訪問響應頭部資訊。
  • 只支援 GET 和 POST 請求。

總結

CORS的本質是通過設定響應頭的欄位實現跨域訪問的,完。

相關文章