跨域方法之CORS

簡介

CORS 全稱:跨域資源共享(Cross-origin resource sharing),主要用來解決因爲同源策略致使的 XMLHttpRequest 和 Fetch 沒法獲取請求資源的問題。html

這裏以 XMLHttpRequest 爲例,server 端以 express 框架爲例前端

分類

瀏覽器將CORS請求分紅兩類:簡單請求和非簡單請求。只要同時知足如下兩大條件,就屬於簡單請求:chrome

1.請求方法是如下三種方法之一:express

  • head
  • get
  • post

2.請求頭不超出如下幾種字段:跨域

  • accept
  • accept-language
  • content-language
  • content-type:只限於三個值,application/x-www-form-urlencoded、multipart/form-data、text/plain

非簡單請求:當不符合上面的條件時,就是非簡單請求。瀏覽器

解決辦法

簡單請求:只須要在 server 端設置請求頭:cookie

res.header('Access-Control-Allow-Origin', '*'); //或者相應的origin
複製代碼

非簡單請求:app

非簡單請求會在正式通訊以前,會增長一次 options 查詢請求,稱爲"預檢"請求(preflight)。這時想要實現跨域資源共享,除了 origin 外,還要設置其餘屬性:cors

let xhr = new XMLHttpRequest(),
    method = 'post',
    url = 'http://127.0.0.1:3000/getData';

xhr.open(method, url, true);
// 自定義頭部
xhr.setRequestHeader('X-requestId', '123456');
xhr.send({ form: 'data' });
xhr.onreadystatechange = function () {
  if(xhr.readyState === 4) {
    console.log('success')
  }
}
複製代碼

好比我在代碼中設置了一個自定義的頭部,那麼此時就須要在 server 設置:框架

res.header('Access-Control-Allow-Headers', 'X-requestId');
複製代碼

除此以外,由於咱們設置跨域通常都是統一設置,所以,能夠加上這個:

res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS'); // 這裏包括你項目中各類請求方法
複製代碼

cookie的問題

在跨域時,想帶上 cookie 須要設置:

// 前端:
xhr.withCredentials = true;

// server端
res.header('Access-Control-Allow-Credentials', true);
複製代碼

注意事項:

  • 攜帶 cookie 時,Access-Control-Allow-Origin 字段必須爲前端請求的origin,不能是 「*」
  • 前端沒法獲取和修改 server 端種到本地的 cookie
  • 在 chrome 瀏覽器裏,cookie 也不會出先在請求頭中(不跨域時是有的)
  • 普通請求若是攜帶 cookies, 也不會觸發「預檢」請求

XMLHttpRequest

CORS請求時,XMLHttpRequest 對象的 getResponseHeader() 方法只能拿到6個基本字段:

  • Cache-Control、
  • Content-Language、
  • Content-Type、
  • Expires、
  • Last-Modified、
  • Pragma。

若是想拿到其餘字段,就必須在服務端 Access-Control-Expose-Headers 裏面指定,例如:

res.header('Access-Control-Expose-Headers', 'X-requestId')
複製代碼

參考連接:

相關文章
相關標籤/搜索