gpt4 book ai didi

node.js - CORS 和 HTTPS 重定向的 Access-Control-Allow-Origin 问题(IIS/IISNode/NodeJS)

转载 作者:太空宇宙 更新时间:2023-11-04 00:20:51 24 4
gpt4 key购买 nike

我有一个分为两部分的 Web 应用程序:

  • 基于 Angular(在 Chrome 下)在 localhost:8000
  • 上运行的“前端”
  • 基于 ExpressJS/NodeJS 的“后端”,运行在 localhost:3000

  • 在尝试逐步将应用程序转换为完全使用 HTTPS 时,我认为首先转换后端会更好。我已经构建了它,以便我可以在后端切换启用/禁用 HTTPS 的能力。

    我已经设置后端运行:
  • 在 IIS 下有两个绑定(bind):http 和 https
  • IISNode 下的 NodeJS 应用程序。

  • 当我尝试在本地开发环境中的 localhost 下运行整个应用程序(前端和后端)时,问题就出现了,但使用的是 HTTP-to-HTTPS 重写(重定向)规则。之后,我在前端收到 CORS 错误。

    简而言之,在我的本地开发环境中,我正在尝试:

    Basic App

    在阅读了 CORS 的所有内容数小时后,我根据 this blog post 调整了 web.config 和 applicationHost.config和 this StackOverflow article试图捕获 Request Origin header 值。这是他们的样子。

    我的 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 应用程序还设置为处理来自 localhost:8000、localhost:3000、localhost:3443(本地 https)和“null”(转换为字符串)的 CORS。 (稍后会详细介绍。)

    但是如果我使用这个配置,那么我会在前端得到以下错误:

    XMLHttpRequest cannot load http://localhost:3000/foo/bar/ Response for preflight is invalid (redirect)



    我怀疑这是因为 IIS 处理了重定向,但结果它正在处理带有无效响应(重定向)的预检检查(HTTP OPTIONS)。然而,根据 this StackOverflow article ,以及 @sideshowbarker 的答案,让我相信当前版本的 Chrome 59.0.3071.104 应该能够处理来自 CORS preflight OPTIONS 请求的 HTTP 重定向响应。

    如果我从 applicationHost.config 和 HTTP-to-HTTPS 重写和其他规则以及 web.config 中删除服务器变量,然后添加代码以允许 NodeJS 应用程序处理重定向到 HTTPS,那么修改后的应用程序看起来像这样:

    Revised App

    然后出现一个未知的(NodeJS?IIS?)服务器错误,因为请求被取消:

    Chrome Dev Tools Networking 1

    Chrome Dev Tools Networking 2

    即使请求中的 Origin 和响应 header 中的 Access-Control-Allow-Origin 匹配,您也可以在 chrome://net-internals/#events 中看到取消:

    Chrome net-internals

    没有有用的错误消息(即使客户端收到一条错误消息),这让我相信是 IIS 而不是 NodeJS 取消了请求并且没有发回任何有用的信息。

    在 NodeJS Lite 服务器(而不是 IIS 作为实验)下运行时,我最终添加了一个“null”条目来处理 CORS,但我需要它在 IIS/IISNode 下运行。但是,然后 IIS/IISNode/NodeJS 组合似乎存在问题。

    我怀疑“null”的请求来源很可能是服务器执行重定向的请求的结果,因为您确实有两个请求:
    - 来自浏览器的原始请求
    - 作为重定向结果的请求
    发生重定向时,我假设重定向请求中的来源与原始 URL 不同,原因在 https://www.w3.org/TR/cors/#generic-cross-origin-request-algorithms 中所述。 ,重定向中的 Origin 请求 header 为空。

    但是,这并不能解释,为什么当我让 NodeJS 处理重定向时 Origin 请求和 Access-Control-Allow-Origin 响应 header 值都为 null 并且请求仍然被取消。 :-/

    最后,如果我消除了任何 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。

    对于这种情况,规范之前要求浏览器停止并且不允许发出请求的前端代码访问响应,并且浏览器会响应如下错误:

    The request was redirected to 'http://localhost:3000/foo/bar/', which is disallowed for cross-origin requests that require preflight.



    请注意,这与为问题中的场景引用的错误消息不同,即:

    XMLHttpRequest cannot load http://localhost:3000/foo/bar/ Response for preflight is invalid (redirect)



    在那种情况下(问题中的那个),这就是发生的情况:
    OPTIONS /documents/123   --> 307 redirect to `/documents/abc`

    即对 OPTIONS 的响应本身就是3xx。该规范仍然需要为此进行预检失败。

    但是对于需要预检情况的其他不允许的跨域请求,规范不再需要失败,并且浏览器中不应再出现该错误; the spec changed in August 2016 to no longer require it ,并且随后更新所有浏览器引擎以匹配该更改。

    Chrome 是最后一个实现更新的浏览器,但 it was fixed in the Chrome sources in December 2016 ,以及 Chrome 57 中提供的修复程序。

    关于node.js - CORS 和 HTTPS 重定向的 Access-Control-Allow-Origin 问题(IIS/IISNode/NodeJS),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44619689/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com