容許跨域資源共享(CORS)攜帶 Cookie

CORS 是一個 W3C 標準,全稱是「跨域資源共享」(Cross-origin resource sharing)。api

默認瀏覽器爲了安全,遵循「同源策略」,不容許 Ajax 跨域訪問資源,而爲了容許這種操做,服務器端和客戶端都要遵循一些約定。跨域

服務器端需設置如下響應頭:瀏覽器

Access-Control-Allow-Origin: <origin> | * // 受權的訪問源
Access-Control-Max-Age: <delta-seconds> // 預檢受權的有效期,單位:秒
Access-Control-Allow-Credentials: true | false // 是否容許攜帶 Cookie
Access-Control-Allow-Methods: <method>[, <method>]* // 容許的請求動詞
Access-Control-Allow-Headers: <field-name>[, <field-name>]* // 額外容許攜帶的請求頭
Access-Control-Expose-Headers: <field-name>[, <field-name>]* // 額外容許訪問的響應頭

咱們看到,Access-Control-Allow-Credentials 響應頭會使瀏覽器容許在 Ajax 訪問時攜帶 Cookie,但咱們仍然須要對 XMLHttpRequest 設置其 withCredentials 參數,才能實現攜帶 Cookie 的目標。安全

示例代碼以下:服務器

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

注意,爲了安全,標準裏不容許 Access-Control-Allow-Origin: *,必須指定明確的、與請求網頁一致的域名。同時,Cookie 依然遵循「同源策略」,只有用目標服務器域名設置的 Cookie 纔會上傳,並且使用 document.cookie 也沒法讀取目標服務器域名下的 Cookie。cookie

下面簡單普及一下 CORS 的有關知識。app

瀏覽器對待 CORS 有兩種規則,一種只有一次請求,一種要多發送一次「預檢查」請求。url

簡單 CORS

同時知足如下條件:code

動詞限制,只容許是:orm

  • HEAD
  • GET
  • POST

請求頭限制,只容許出現:

  • Accept
  • Accept-Language
  • Content-Language
  • Last-Event-ID
  • Content-Type 且只容許是:
    • application/x-www-form-urlencoded
    • multipart/form-data
    • text/plain

簡單請求瀏覽器會直接發送該請求,並附加 Origin 頭,好比:

Origin: localhost:8080

服務器會返回:

Access-Control-Allow-Origin: http://localhost:8080
Access-Control-Max-Age: 600
Access-Control-Allow-Credentials: true
Access-Control-Expose-Headers: X-Custom-Header

瀏覽器在收到服務器返回時,先檢查是否容許訪問,不容許則直接報錯(可用 XMLHttpRequest.onerror 捕獲)。

帶預檢查的 CORS

不知足簡單 CORS 要求的請求,在正式請求前,瀏覽器會發送一次 OPTIONS 動詞的請求。

例如欲請求 PUT /xxx,想額外發送 X-Custom-Header 頭,則會先發送:

OPTIONS /xxx HTTP/1.1
Origin: http://api.bob.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: X-Custom-Header
Host: localhost:8080

服務器返回:

HTTP/1.1 200 OK
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: X-Custom-Header
Access-Control-Allow-Methods: PUT
Access-Control-Allow-Origin: http://localhost:8080
Access-Control-Max-Age:600
Allow: GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, PATCH
Vary: Origin

瀏覽器檢查完,一切順利,才發送真正的請求。

相關文章
相關標籤/搜索