黑人生命至上。
支持平等正義倡議.

cors

NPM Version NPM Downloads Build Status Test Coverage

CORS 是 node.js 套件,用於提供 Connect/Express 中介軟體,可用於啟用 CORS,並提供各種選項。

在 Twitter 上追蹤我 (@troygoode)!

安裝

這是一個 Node.js 模組,可透過 npm 註冊 取得。安裝時使用 npm install 指令

$ npm install cors

用法

簡單用法(啟用所有 CORS 要求)

var express = require('express')
var cors = require('cors')
var app = express()

app.use(cors())

app.get('/products/:id', function (req, res, next) {
  res.json({msg: 'This is CORS-enabled for all origins!'})
})

app.listen(80, function () {
  console.log('CORS-enabled web server listening on port 80')
})

為單一路由啟用 CORS

var express = require('express')
var cors = require('cors')
var app = express()

app.get('/products/:id', cors(), function (req, res, next) {
  res.json({msg: 'This is CORS-enabled for a Single Route'})
})

app.listen(80, function () {
  console.log('CORS-enabled web server listening on port 80')
})

設定 CORS

var express = require('express')
var cors = require('cors')
var app = express()

var corsOptions = {
  origin: 'http://example.com',
  optionsSuccessStatus: 200 // some legacy browsers (IE11, various SmartTVs) choke on 204
}

app.get('/products/:id', cors(corsOptions), function (req, res, next) {
  res.json({msg: 'This is CORS-enabled for only example.com.'})
})

app.listen(80, function () {
  console.log('CORS-enabled web server listening on port 80')
})

使用動態來源設定 CORS

此模組支援使用提供給 origin 選項的函式,動態驗證來源。此函式會傳遞一個字串,也就是來源(或在要求沒有來源時傳遞 undefined),以及具有簽章 callback(error, origin)callback

傳遞給 callback 的 origin 參數可以是中介軟體的 origin 選項允許的任何值,函式除外。請參閱 設定選項 部分,以取得所有可能值類型的更多資訊。

此函式旨在允許從後端資料來源(例如資料庫)動態載入允許的來源。

var express = require('express')
var cors = require('cors')
var app = express()

var corsOptions = {
  origin: function (origin, callback) {
    // db.loadOrigins is an example call to load
    // a list of origins from a backing database
    db.loadOrigins(function (error, origins) {
      callback(error, origins)
    })
  }
}

app.get('/products/:id', cors(corsOptions), function (req, res, next) {
  res.json({msg: 'This is CORS-enabled for an allowed domain.'})
})

app.listen(80, function () {
  console.log('CORS-enabled web server listening on port 80')
})

啟用 CORS 預檢

某些 CORS 要求被視為「複雜」,需要一個初始的 OPTIONS 要求(稱為「預檢要求」)。「複雜」CORS 要求的範例包括使用 GET/HEAD/POST 以外的 HTTP 動詞(例如 DELETE)或使用自訂標頭。若要啟用預檢,您必須為您想要支援的路由新增一個新的 OPTIONS 處理常式

var express = require('express')
var cors = require('cors')
var app = express()

app.options('/products/:id', cors()) // enable pre-flight request for DELETE request
app.del('/products/:id', cors(), function (req, res, next) {
  res.json({msg: 'This is CORS-enabled for all origins!'})
})

app.listen(80, function () {
  console.log('CORS-enabled web server listening on port 80')
})

您也可以像這樣啟用全面預檢

app.options('*', cors()) // include before other routes

注意:當使用此中介軟體作為應用程式層級中介軟體時(例如,app.use(cors())),預檢要求已針對所有路由處理。

非同步設定 CORS

var express = require('express')
var cors = require('cors')
var app = express()

var allowlist = ['http://example1.com', 'http://example2.com']
var corsOptionsDelegate = function (req, callback) {
  var corsOptions;
  if (allowlist.indexOf(req.header('Origin')) !== -1) {
    corsOptions = { origin: true } // reflect (enable) the requested origin in the CORS response
  } else {
    corsOptions = { origin: false } // disable CORS for this request
  }
  callback(null, corsOptions) // callback expects two parameters: error and options
}

app.get('/products/:id', cors(corsOptionsDelegate), function (req, res, next) {
  res.json({msg: 'This is CORS-enabled for an allowed domain.'})
})

app.listen(80, function () {
  console.log('CORS-enabled web server listening on port 80')
})

設定選項

  • origin:設定 Access-Control-Allow-Origin CORS 標頭。可能的值
    • 布林值 - 將 origin 設為 true 以反映 req.header('Origin') 所定義的 請求來源,或將其設為 false 以停用 CORS。
    • 字串 - 將 origin 設為特定來源。例如,如果您將其設為 "http://example.com",則只會允許來自 “http://example.com” 的請求。
    • 正規表示法 - 將 origin 設為正規表示法模式,用於測試請求來源。如果符合,則會反映請求來源。例如,模式 /example\.com$/ 將反映任何來自以 “example.com” 結尾的來源的請求。
    • 陣列 - 將 origin 設為有效來源的陣列。每個來源可以是 字串正規表示法。例如,["http://example1.com", /\.example2\.com$/] 將接受來自 “http://example1.com” 或 “example2.com” 的子網域的任何請求。
    • 函式 - 將 origin 設為實作一些自訂邏輯的函式。該函式將請求來源作為第一個參數,並將回呼(稱為 callback(err, origin),其中 originorigin 選項的非函式值)作為第二個參數。
  • 方法:設定 Access-Control-Allow-Methods CORS 標頭。預期逗號分隔的字串(例如:‘GET,PUT,POST’)或陣列(例如:['GET', 'PUT', 'POST'])。
  • 允許標頭:設定 Access-Control-Allow-Headers CORS 標頭。預期逗號分隔的字串(例如:‘Content-Type,Authorization’)或陣列(例如:['Content-Type', 'Authorization'])。如果未指定,則預設反映請求的 Access-Control-Request-Headers 標頭中指定的標頭。
  • 公開標頭:設定 Access-Control-Expose-Headers CORS 標頭。預期逗號分隔的字串(例如:‘Content-Range,X-Content-Range’)或陣列(例如:['Content-Range', 'X-Content-Range'])。如果未指定,則不公開任何自訂標頭。
  • 憑證:設定 Access-Control-Allow-Credentials CORS 標頭。設為 true 以傳遞標頭,否則會略過。
  • 最大年齡:設定 Access-Control-Max-Age CORS 標頭。設為整數以傳遞標頭,否則會略過。
  • preflightContinue:將 CORS 預檢測回應傳遞至下一個處理常式。
  • optionsSuccessStatus:提供狀態碼,用於成功的 OPTIONS 要求,因為某些舊版瀏覽器(IE11、各種 SmartTV)會在 204 中中斷。

預設組態等同於

{
  "origin": "*",
  "methods": "GET,HEAD,PUT,PATCH,POST,DELETE",
  "preflightContinue": false,
  "optionsSuccessStatus": 204
}

有關每個 CORS 標頭效果的詳細資訊,請閱讀 web.dev 上的 這篇文章

示範

說明使用 React 說明 CORS 運作(以及不運作)的示範,請參閱此處:https://node-cors-client.netlify.com

該示範的程式碼可以在此處找到

授權

MIT 授權

作者

Troy Goode (troygoode@gmail.com)