本文闡述CROS跨域原理及配置方式,其他跨域方案參考,

相關:

跨域解決方案(待補充)

HTTP請求詳解


跨域的本質是,在A域下訪問非A域的資源(假定是資源B),普通發起的跨域資源請求是會被允許的,

比如,站點 domain-a.com 的某 HTML 頁面通過<img> 的 src請求 http://domain-b.com/image.jpg。網路上的許多頁面都會載入來自不同域的CSS樣式表,圖像和腳本等資源。

但是在腳本中發起的請求資源B,出於安全原因,瀏覽器會到資源B伺服器去詢問:A域是否可以獲取資源B?如果可以則進行後續請求,如果不行,瀏覽器會在console面板顯示一個禁止跨域的錯誤提示。

先簡單說明一下CROS跨域流程

1、瀏覽器接收到腳本發起的請求(資源B),

2、發送一個簡單的預檢請求(OPTIONS)到資源B所在伺服器

3、資源B伺服器響應,告訴瀏覽器該請求(包括請求域,請求方法)可通行

4、瀏覽器發送完整請求到資源B伺服器

5、資源B伺服器響應,返回完整請求

預檢請求:method是options,response headers返回服務端跨域配置
正常請求:method是post


CROS服務端配置:

Access-Control-Allow-Origin: <origin> | *

origin 參數的值指定了允許訪問該資源的外域 URI,可以指定該欄位的值為通配符(*),表示允許來自所有域的請求。

Access-Control-Allow-Methods: <method>[, <method>]*

指明瞭實際請求所允許使用的 HTTP 方法。

Access-Control-Allow-Headers: <field-name>[, <field-name>]*

指明瞭實際請求中允許攜帶的首部欄位。

Access-Control-Allow-Credentials: true

一般而言,對於跨域 XMLHttpRequest或 Fetch 請求,瀏覽器不會發送身份憑證信息。如果要發送憑證信息,需要設置為true。

Access-Control-Max-Age: <delta-seconds>

指定預檢請求的緩存時間(單位:秒),有效期內的後續該請求不再進行預檢。若不設置則每次請求都需要先發起預檢。

Access-Control-Expose-Headers

該項使用較少,不明瞭,引用如下:

在跨域訪問時,XMLHttpRequest對象的getResponseHeader()方法只能拿到一些最基本的響應頭,Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma,如果要訪問其他頭,則需要伺服器設置本響應頭。

Access-Control-Expose-Headers頭讓伺服器把允許瀏覽器訪問的頭放入白名單,例如:

Access-Control-Expose-Headers: X-My-Custom-Header, X-Another-Custom-Header

這樣瀏覽器就能夠通過getResponseHeader訪問X-My-Custom-HeaderX-Another-Custom-Header 響應頭了

node.js設置CROS示例代碼

// ...
app.use(function (req, res, next) {
res.set({
"Access-Control-Allow-Origin": "www.a.com",
"Access-Control-Allow-Credentials": true,
"Access-Control-Allow-Headers": "Content-Type, Content-Length, Authorization, Origin, Accept, X-Requested-With",
"Access-Control-Allow-Methods": "*",
"Access-Control-Max-Age": 86400
})
next();
});


參考:

  • HTTP訪問控制(CORS)
  • 瀏覽器的同源策略

推薦閱讀:

相關文章