C O R S簡述

C O R S

全部前端工程師都知道跨域問題(不一樣的協議、域、端口),也都知道解決跨域的常見方式是經過設置cors。 那麼cors究竟是什麼,它是如何解決跨域問題的呢前端

CORS全稱Cross-Origin Resource Sharing,即跨域資源共享。是解決跨域問題常見的方式。api

簡單請求和非簡單請求

知足如下條件即視爲簡單請求跨域

  • 請求方法爲如下任意方法之一(在W3C規範中也稱爲簡單方法 simple method瀏覽器

    • GET
    • HEAD
    • POST
  • 請求頭只能包含如下字段 (在W3C規範中前4種稱爲簡單頭部 simple header,不包括瀏覽器自動設置的那些,好比User-Agent,Connection等)緩存

    • Accept
    • Accept-Language
    • Content-Language
    • Content-Type (僅支持 application/x-www-form-urlencoded 、multipart/form-data 、text/plain)
    • DPR
    • Downlink
    • Save-Data
    • Viewport-Width
    • Width
  • 請求中的XMLHttpRequestUpload對象沒有註冊事件監聽
  • 請求中沒有使用 ReadableStream 對象。

對於簡單請求,瀏覽器會直接發起實際跨域請求,只要返回頭部中設置了正確的Access-Control-Allow-Origin字段便可成功請求,不然你會在瀏覽器的console面板看到相似於下面這樣報錯cookie

Access to XMLHttpRequest at 'http://domain.com/api/test' from origin 'http://localhost:1234' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.前端工程師

對於非簡單請求,在發起實際的請求以前,瀏覽器會發起一個預檢請求(preflight request),這是個options請求,包含如下字段app

  • Access-Control-Request-Method (表示實際發生的請求方法)
  • Access-Control-Request-Headers (若是實際的請求頭部不爲空,則會將實際的請求頭部中用到的字段放入該字段中)
  • Origin (表示請求來源)

當預檢請求經過後,纔會發起真實的請求,不然你會在瀏覽器的console面板看到相似於下面這樣報錯(這裏是請求頭沒有經過預檢)cors

Access to XMLHttpRequest at 'http://domain.com/api/test' from origin 'http://localhost:1234' has been blocked by CORS policy: Request header field custom-header is not allowed by Access-Control-Allow-Headers in preflight response.dom

另外,須要同時對接口的options方法以及真實的getpost方法設置對應的返回頭。若是隻設置了真實請求方法的返回頭,而沒有相應設置options方法的返回頭,預檢也不會經過。你會在瀏覽器的console面板看到相似於下面這樣報錯

Access to XMLHttpRequest at 'http://domain.com/api/test' from origin 'http://localhost:1234' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

並不是全部非簡單方法都會發起預檢請求

預檢請求是有緩存的!在預檢請求的返回頭中設置Access-Control-Max-Age字段,值爲int類型,表明過時時間,單位是秒。 在該時間段以內,非簡單方法發送跨域請求不會再事先發起預檢請求。

response header

對於預檢請求,能夠返回下列字段

  • Access-Control-Allow-Origin (容許的域)
  • Access-Control-Allow-Method (容許的請求方法,簡單請求可不列出,也就是說即便你只設置了POST,GET方法也是會經過的)
  • Access-Control-Allow-Headers (容許的請求頭部)
  • Access-Control-Max-Age (緩存時間,上面已經介紹過了)
  • Access-Control-Allow-Credentials(是否容許攜帶用戶認證信息 cookie , HTTP authentication等,當該值爲true時,Access-Control-Allow-Origin不能爲*,當該值爲false,同時請求又攜帶了credentials,該請求的返回會被瀏覽器忽略)
  • Access-Control-Expose-Headers (能夠暴露給瀏覽器的頭部)

本文主要知識來源並推薦閱讀:

MDN
W3C

相關文章
相關標籤/搜索