一尘不染

为什么不将CORS标头添加到OPTIONS路由允许浏览器访问我的API?

node.js

我试图在使用Express.js
Web框架的Node.js应用程序中支持CORS。我已经阅读有关如何处理此问题的Google小组讨论,并阅读了一些有关CORS工作原理的文章。首先,我做到了(代码是用CoffeeScript语法编写的):

app.options "*", (req, res) ->
  res.header 'Access-Control-Allow-Origin', '*'
  res.header 'Access-Control-Allow-Credentials', true
  # try: 'POST, GET, PUT, DELETE, OPTIONS'
  res.header 'Access-Control-Allow-Methods', 'GET, OPTIONS'
  # try: 'X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept'
  res.header 'Access-Control-Allow-Headers', 'Content-Type'
  # ...

它似乎不起作用。看来我的浏览器(Chrome)没有发送初始的OPTIONS请求。当我刚刚更新资源块时,我需要向以下站点提交跨域GET请求:

app.get "/somethingelse", (req, res) ->
  # ...
  res.header 'Access-Control-Allow-Origin', '*'
  res.header 'Access-Control-Allow-Credentials', true
  res.header 'Access-Control-Allow-Methods', 'POST, GET, PUT, DELETE, OPTIONS'
  res.header 'Access-Control-Allow-Headers', 'Content-Type'
  # ...

它可以工作(在Chrome中)。这也适用于Safari。

我读过…

在实现CORS的浏览器中,每个跨域的GET或POST请求都带有一个OPTIONS请求,该请求检查GET或POST是否正常。

所以我的主要问题是,在我看来,这种情况怎么似乎没有发生?为什么不调用我的app.options块?为什么需要在主app.get块中设置标题?


阅读 272

收藏
2020-07-07

共1个答案

一尘不染

要回答您的主要问题,如果POST或GET中包含任何非简单的内容或标头,则CORS规范仅要求OPTIONS调用位于POST或GET之前。

需要CORS飞行前请求(OPTIONS调用)的内容类型是 除以下 内容 之外的 任何内容类型:

  1. application/x-www-form-urlencoded
  2. multipart/form-data
  3. text/plain

除上面列出的内容类型外,任何其他内容类型都会触发飞行前请求。

对于标头, 除以下内容外 ,任何请求标头都会触发预检请求:

  1. Accept
  2. Accept-Language
  3. Content-Language
  4. Content-Type
  5. DPR
  6. Save-Data
  7. Viewport-Width
  8. Width

其他任何请求标头都将触发飞行前请求。

因此,您可以添加一个自定义标头,例如:x-Trigger: CORS,它应该触发飞行前请求并点击OPTIONS块。

请参阅《MDN Web API参考-CORS预检请求》

2020-07-07