访问控制允许来源与CORS问题和HTTPS重定向(IIS/IISNode /的NodeJS)
我有一个Web应用程序,它由两个部分组成:访问控制允许来源与CORS问题和HTTPS重定向(IIS/IISNode /的NodeJS)
- 总部设在角的“前端”( Chrome会)在本地主机上运行:8000
- 的“后端”立足ExpressJS /的NodeJS,在本地主机上运行:3000
在试图逐步转换为完全使用HTTPS应用,我想它会首先转换后端更好。我已经构建它,以便我可以切换在后端启用/禁用HTTPS的功能。
我已经设置了后台运行:
- 有两个下IIS绑定:http和https
- IISNode下的应用程序的NodeJS。
问题来了,当我尝试运行整个应用程序(前端和后端)在本地主机在本地的发展环境,但与HTTP到HTTPS的重写(重定向)规则。之后,我在前端收到CORS错误。
总之,在我的本地开发环境,我试图:
阅读所有的东西CORS了几个小时后,我调整基于this blog post web.config中和的applicationHost.config和this * article试图捕获请求源标头值。这是他们的样子。
我的applicationHost.config包含此部分:
<location path="Default Web Site">
<system.webServer>
<rewrite>
<allowedServerVariables>
<add name="CAPTURED_ORIGIN" />
<add name="RESPONSE_Access-Control-Allow-Origin" />
</allowedServerVariables>
</rewrite>
</system.webServer>
</location>
这里是我的的Web.config:
<?xml version="1.0" encoding="utf-8"?>
<!--
This configuration file is required if iisnode is used to run node processes behind
IIS or IIS Express. For more information, visit:
https://github.com/tjanczuk/iisnode/blob/master/src/samples/configuration/web.config
-->
<configuration>
<system.webServer>
<handlers>
<!-- Indicates that the server.js file is a node.js site to be handled by the iisnode module -->
<add name="iisnode" path="bin/www" verb="*" modules="iisnode" />
</handlers>
<rewrite>
<rules>
<rule name="Capture Origin Header">
<match url=".*" />
<conditions>
<add input="{HTTP_ORIGIN}" pattern=".+" />
</conditions>
<serverVariables>
<set name="CAPTURED_ORIGIN" value="{C:0}" />
</serverVariables>
<action type="None" />
</rule>
<!-- HTTP-to-HTTPS redirect -->
<rule name="Redirect to HTTPS" enabled="true" stopProcessing="true">
<match url="(.*)" ignoreCase="true" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="true">
<add input="{HTTPS}" pattern="^off$" />
<add input="{HTTP_HOST}" pattern="([^/:]*?):[^/]*?" />
</conditions>
<action type="Redirect" url="https://{C:1}:3443/{R:0}" appendQueryString="true" redirectType="Temporary" />
</rule>
<!-- First we consider whether the incoming URL matches a physical file in the /public folder -->
<rule name="StaticContent">
<action type="Rewrite" url="public{REQUEST_URI}" />
</rule>
<!-- All other URLs are mapped to the node.js site entry point -->
<rule name="DynamicContent">
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="True" />
</conditions>
<action type="Rewrite" url="bin/www" />
</rule>
</rules>
<outboundRules>
<rule name="Set-Access-Control-Allow-Origin for known origins">
<match serverVariable="RESPONSE_Access-Control-Allow-Origin" pattern=".+" negate="true" />
<action type="Rewrite" value="{CAPTURED_ORIGIN}" />
</rule>
</outboundRules>
</rewrite>
<!-- Make sure error responses are left untouched -->
<httpErrors existingResponse="PassThrough" />
</system.webServer>
<appSettings>
<add key="HTTPS_ENABLED" value="true" />
</appSettings>
</configuration>
的应用程序的NodeJS还设立了处理从本地主机CORS :8000,localhost:3000,localhost:3443(本地https)和“null”(转换为字符串)。 (更多的是,后来)
但是,如果我用这个配置,然后我得到的前端以下错误:
的XMLHttpRequest不能加载 http://localhost:3000/foo/bar/的预检 响应无效(重定向)
我怀疑这是因为IIS处理重定向,但结果是处理前检查(HTTP选项),无效响应(重定向)。然而,根据this * article,并@sideshowbarker答案,使我相信,铬,59.0.3071.104的当前版本,应该能够处理从CORS预检OPTIONS请求的HTTP重定向响应。
如果我删除从的applicationHost.config服务器变量和HTTP到HTTPS的重写和其他规则,并从网络。配置,然后添加代码,允许的NodeJS应用程序来处理重定向到HTTPS,然后将修改后的应用程序如下:(?的NodeJS IIS)
随后便出现一个未知的发生是由于服务器错误该请求被取消:
您可以在Chrome中看到撤销://网内部/#事件甚至ŧ霍夫在响应报头的请求,并且所述访问控制允许来源起源匹配:
有(即使一个正由客户端接收的)没有有用的错误消息,这导致我相信它是IIS,而不是NodeJS取消请求并返回没有有用的信息。
我最终在NodeJS Lite服务器(而不是IIS作为实验)下运行时添加了一个“null”条目来处理CORS,但我需要在IIS/IISNode下运行该条目。但是,那么IIS/IISNode/NodeJS组合似乎存在问题。
我怀疑是“空”的请求源是最有可能的一个请求,该服务器执行重定向的结果,因为你真的有两个要求: - 从浏览器 的原始请求 - 该请求是重定向的结果 发生重定向时,我假设重定向请求中的原点与原始URL不同,并且由于https://www.w3.org/TR/cors/#generic-cross-origin-request-algorithms中所述的原因,重定向内的Origin请求标头为空。
但是,这并不能解释为什么当我让NodeJS处理重定向时,Origin请求和Access-Control-Allow-Origin响应标头值都为空,并且请求仍然被取消。 : -/
最后,如果我消除了HTTP到HTTPS重定向的任何尝试,那么应用程序在我的开发环境中工作正常。
对预印OPTIONS
本身的响应本身必须始终是2xx成功响应,例如200或204.对印前检查本身的响应永远不会是重定向 - 例如302.规范禁止这样做。
但问题中引用的响应显示服务器响应这样的重定向;因此引用了错误消息。如果浏览器获得对预检OPTIONS请求的3xx响应,该规范要求浏览器停在那里 - 将预检视为失败。
所以唯一的解决办法是修复服务器,因此它不会给那个OPTIONS
的重定向响应。
在CORS request with Preflight and redirect: disallowed. Workarounds?问题中描述的重定向和预检有一种不同的情况。在这种情况下,这是发生了什么:
OPTIONS /documents/123 --> 204 (everything okay, please proceed)
GET /documents/123 --> 303 redirect to `/documents/abc`
也就是说,到OPTIONS
请求本身的响应是一个2xx成功,但到前端代码发送后继实际请求的响应是一个3XX。
针对该方案,该规范以前需要浏览器停止,不要让前端代码使得能够获得响应请求,浏览器将通过类似的错误回应:
请求被重定向到'
http://localhost:3000/foo/bar/
', ,这是不允许需要预检的跨源请求。
注意这比列举了在问题方案中的错误信息,这是不同的:
的XMLHttpRequest无法加载预检
http://localhost:3000/foo/bar/
响应 无效(重定向)
在那种情况(问题中的那个),而是发生了什么:
OPTIONS /documents/123 --> 307 redirect to `/documents/abc`
也就是说,对OPTIONS
本身的响应是3xx。该规范仍然需要预检失败。
但是,对于其他不允许用于需要预检的跨源请求的情况下,规范不再需要失败,并且该错误不应再发生在浏览器中; the spec changed in August 2016 to no longer require it,并且随后更新所有浏览器引擎以匹配该更改。
铬是实现更新的最后一个浏览器,但it was fixed in the Chrome sources in December 2016,并运在Chrome修复57
https://*.com/questions/42168773/how-to-resolve-preflight-is-无效重定向在Cors/42172732#42172732是不同的情况。对于预检OPTIONS本身的响应必须始终是20倍的成功响应,例如200或204.对预检本身的响应永远不可能是重定向302或其他。规范禁止这一点。但是您提出请求的服务器正在响应这样的重定向;因此你看到的错误信息。因此,唯一的解决方案是修复服务器,使得您不需要该OPTIONS请求的重定向响应。 – sideshowbarker
@sideshowbarker我想知道你是否会出现。你以前的回应的粉丝。 :-)那么,当使用HTTP到HTTPS重写规则时,似乎某些Web服务器(IIS)被破坏了?这是我不明白的部分。使用IIS重写规则,我的理解是,对浏览器没有立即响应,但服务器重定向,然后提供响应。这是我感到困惑的。您是否在尝试处理CORS预检请求时无法使用HTTPS重定向规则? – jhenderson2099
@sideshowbarker - 也是您在https://*.com/questions/42168773/how-to-resolve-preflight-is-invalid-redirect-in-cors/42172732#42172732的回复表示“浏览器未遵循重定向对于CORS预检不再符合规范,但浏览器需要更新他们的实现以符合规范更改“这就是让我相信3xx回复正常的原因 – jhenderson2099