[Express] CORS
Express 框架中, 要處理 CORS 規範設定,
可以依程式需求手動配置 res.header()
, 或是使用 express/cors 套件.
Manually
Allow-Origin: *
要允許不同 Origin 存取資料, Server 端在 response header 加上 Access-Control-Allow-Origin
.
Express 框架語法如下:
app.use((req, res, next)=> {
res.header('Access-Control-Allow-Origin', *)
res.header('Access-Control-Allow-Credentials', false)
next()
})
如果 Access-Control-Allow-Origin 設定為* (接受任何跨領域的讀取),
Access-Control-Allow-Credentials
只能設定為 false,
說明連結
use credentials
因為設定 Access-Control-Allow-Credentials
為 false, 所以 client 不能傳送 cookie.
若需要跨 subdomain 存取 cookies credentials, 可以使用白名單的設計.
const allowedOrigins = ['http://xxx.star.com.tw', 'http://yyy.star.com.tw', 'http://zzz.star.com.tw']
const origin = req.headers.origin
if (allowedOrigins.indexOf(origin) > -1){
res.setHeader('Access-Control-Allow-Origin', origin)
}
res.header('Access-Control-Allow-Credentials', true)
如果符合 allowedOrigins 就可以接受 Credentials.
express/cors
Express 處理 CORS 設定雖然簡單, 但寫在程式中寫死 header 設置, 在維護修改都比較麻煩. 不同開發環境部署上也比較沒有彈性.
Express 官方自己出了一個套件 express/cors 方便大家在 Node.js 上設定 CORS:
npm install --save cors
var cors = require(cors)
app.use(cors())
這樣就完成了. 但不是最好的配置方式, 因為 cors 預設為開好開滿, 所有跨域請求都接受:
{
"origin": "*",
"methods": "GET,HEAD,PUT,PATCH,POST,DELETE",
"preflightContinue": false,
"optionsSuccessStatus": 204
}
比較好的作法應該是授權指定的網域, 請求方法等, 針對需求去設定:
const corsOptions = {
origin: [
'http://www.example.com',
'http://localhost:8080',
],
methods: 'GET,HEAD,PUT,PATCH,POST,DELETE,OPTIONS',
allowedHeaders: ['Content-Type', 'Authorization'],
};
app.use(cors(corsOptions));
注意 cors options 為一標準的 JSON 格式, 可以載入外部 config.json 檔使用, 就可以完成不同開發環境下的不同配置需求了.
參數
- origin 設置可存取的網域, 也就是設置 Access-Control-Allow-Origin 參數.
可接受的資料型別為Boolean
|String
|RegExp
|Array<String|RegExp>
|Function
- methods 設置可存取的方法, 也就是設置 Access-Control-Allow-Methods 參數.
可以接受的參數格式:GET, POST,DELETE
這種用逗號隔開的. 也接受Array<String>
的格式, 如:['GET', 'POST']
- allowedHeaders 設置可存取的 Header,也就是設置 Access-Control-Allow-Headers 參數,
可以接受的參數格式:Content-Type,Authorization
這種用逗號隔開的. 也接受Array<String>
的格式, 如:'Content-Type', 'Authorization'
- exposedHeaders 設置瀏覽器可檢視的其他 Header 項目, 也就是設置 Access-Control-Expose-Headers 參數.
可以接受的參數格式:
Content-Range,X-Content-Range
這種用逗號隔開的. 也接受Array<String>
的格式, 如:['Content-Range', 'X-Content-Range']
- credentials 設置是否傳送 cookie, 也就是設置 Access-Control-Allow-Credentials 參數.
資料型別
Boolean
. - maxAge 設置合法期間, 使瀏覽器在這段期間內不必發送 OPTION 請求, 也就是設置 Access-Control-Max-Age 參數.
資料型別
Number
且需整數 - preflightContinue 傳遞 OPTION 請求的 response 到下一個 handler
- optionsSuccessStatus 設置當 OPTION 請求成功時, 回傳的 HTTP Code