我试图在使用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块中设置标题?
要回答您的主要问题,如果POST或GET中包含任何非简单的内容或标头,则CORS规范仅要求OPTIONS调用位于POST或GET之前。
需要CORS飞行前请求(OPTIONS调用)的内容类型是 除以下 内容 之外的 任何内容类型:
application/x-www-form-urlencoded
multipart/form-data
text/plain
除上面列出的内容类型外,任何其他内容类型都会触发飞行前请求。
对于标头, 除以下内容外 ,任何请求标头都会触发预检请求:
Accept
Accept-Language
Content-Language
Content-Type
DPR
Save-Data
Viewport-Width
Width
其他任何请求标头都将触发飞行前请求。
因此,您可以添加一个自定义标头,例如:x-Trigger: CORS,它应该触发飞行前请求并点击OPTIONS块。
x-Trigger: CORS
请参阅《MDN Web API参考-CORS预检请求》