如何解析 'preflight is invalid (redirect)' 或 'redirect is not allowed for a preflight request'
How to resolve 'preflight is invalid (redirect)' or 'redirect is not allowed for a preflight request'
我已按照此步骤设置我的服务器以启用 CORS。
https://docs.microsoft.com/en-us/aspnet/web-api/overview/security/enabling-cross-origin-requests-in-web-api
但现在在我的浏览器开发控制台中,我看到了这条错误消息:
XMLHttpRequest cannot load https://serveraddress/abc. Response for
preflight is invalid (redirect)
你知道我能做些什么来解决它吗?我正在 HTTPS 中发出 CORS 请求。我认为这是导致 'preflight is invalid (redirect)' 失败的原因。但我不知道为什么或什么在重定向 OPTIONS 请求。
谢谢。
简答:在您的代码中提出请求 URL 不缺少尾部斜线。
一个 missing-trailing-slash 问题是问题中引用错误的 most-common 原因。
但这不是 唯一的 原因 — 只是最常见的原因。继续阅读以了解更多详情。
当您看到此错误时,表示您的代码正在触发浏览器发送 CORS preflight OPTIONS
request,并且服务器正在响应 3xx
重定向。为避免该错误,您的请求需要获得 2xx
成功响应。
您可以调整代码以避免触发浏览器发送 OPTIONS
请求。
至于在这种情况下发生的一切,重要的是要知道浏览器在以下情况下进行 CORS 预检:
- 请求方法不是
GET
、HEAD
或 POST
- 您已设置自定义请求 headers 除了
Accept
、Accept-Language
、Content-Language
、Content-Type
、DPR
、Downlink
、Save-Data
、Viewport-Width
或 Width
Content-Type
请求 header 的值不是 application/x-www-form-urlencoded
、multipart/form-data
或 text/plain
如果您无法更改代码以避免浏览器需要进行预检,另一种选择是:
- 在对
OPTIONS
请求的响应中检查Location
响应中的URLheader。
- 更改您的代码,改为直接向另一个 URL 发出请求。
URL 之间的区别可能与路径中的尾部斜杠一样简单 — 例如,您可能需要更改代码中的 URL 以添加尾部斜杠— 例如,http://localhost/api/auth/login/
(注意尾部斜杠)而不是 http://localhost/api/auth/login
(没有尾部斜杠)——或者您可能需要删除尾部斜杠。
您可以使用浏览器 devtools 中的网络窗格来检查对 OPTIONS
请求的响应,并在 Location
响应 [=106] 的值中找到重定向 URL =].
但是,在某些情况下,以下所有情况都为真:
- 你无法避免预检
OPTIONS
- 您无法对请求进行任何调整URL
- 您无法用完全不同的 URL
替换请求 URL
出现这些情况的一个常见情况是,当您尝试使用某些需要 OAuth 或 SSO 工作流的第 3 方端点时,该工作流不打算从前端代码中使用。
在这种情况下——实际上,在所有情况下——必须认识到,对预检的响应必须来自前端代码向其发送请求的同一来源。
因此,即使您创建了一个您控制的 server-side 代理:
- 如果您的浏览器向您的代理发送预检
OPTIONS
请求。
- 您已将代理配置为仅将请求重定向到第 3 方端点。
- 因此,您的前端最终会直接从该第 3 方端点接收响应。
...然后预检将失败。
在这种情况下,最终您唯一的选择是:确保预检不只是重定向到第 3 方端点,而是您自己的 server-side(代理)代码接收来自该端点的响应,消耗它,然后将自己的响应发送回您的前端代码。
当您尝试将 https 服务调用为 http 时,有时会发生这种情况,例如,当您对以下内容执行请求时:
应该是:
'https://example.com/api/v2/tickets'
首先,确保你在 headers
中有 "Access-Control-Allow-Origin": "*"
然后只需删除 url
末尾的“/”
例如变化
url: "https://facebook/api/login/"
进入
url: "https://facebook/api/login" (without '/')
在我的例子中,我不必将请求 header 设置为具有“Access-Control-Allow-Origin”:“*”。 url 必须以“/”结尾
我已按照此步骤设置我的服务器以启用 CORS。 https://docs.microsoft.com/en-us/aspnet/web-api/overview/security/enabling-cross-origin-requests-in-web-api
但现在在我的浏览器开发控制台中,我看到了这条错误消息:
XMLHttpRequest cannot load https://serveraddress/abc. Response for preflight is invalid (redirect)
你知道我能做些什么来解决它吗?我正在 HTTPS 中发出 CORS 请求。我认为这是导致 'preflight is invalid (redirect)' 失败的原因。但我不知道为什么或什么在重定向 OPTIONS 请求。
谢谢。
简答:在您的代码中提出请求 URL 不缺少尾部斜线。
一个 missing-trailing-slash 问题是问题中引用错误的 most-common 原因。
但这不是 唯一的 原因 — 只是最常见的原因。继续阅读以了解更多详情。
当您看到此错误时,表示您的代码正在触发浏览器发送 CORS preflight OPTIONS
request,并且服务器正在响应 3xx
重定向。为避免该错误,您的请求需要获得 2xx
成功响应。
您可以调整代码以避免触发浏览器发送 OPTIONS
请求。
至于在这种情况下发生的一切,重要的是要知道浏览器在以下情况下进行 CORS 预检:
- 请求方法不是
GET
、HEAD
或POST
- 您已设置自定义请求 headers 除了
Accept
、Accept-Language
、Content-Language
、Content-Type
、DPR
、Downlink
、Save-Data
、Viewport-Width
或Width
Content-Type
请求 header 的值不是application/x-www-form-urlencoded
、multipart/form-data
或text/plain
如果您无法更改代码以避免浏览器需要进行预检,另一种选择是:
- 在对
OPTIONS
请求的响应中检查Location
响应中的URLheader。 - 更改您的代码,改为直接向另一个 URL 发出请求。
URL 之间的区别可能与路径中的尾部斜杠一样简单 — 例如,您可能需要更改代码中的 URL 以添加尾部斜杠— 例如,http://localhost/api/auth/login/
(注意尾部斜杠)而不是 http://localhost/api/auth/login
(没有尾部斜杠)——或者您可能需要删除尾部斜杠。
您可以使用浏览器 devtools 中的网络窗格来检查对 OPTIONS
请求的响应,并在 Location
响应 [=106] 的值中找到重定向 URL =].
但是,在某些情况下,以下所有情况都为真:
- 你无法避免预检
OPTIONS
- 您无法对请求进行任何调整URL
- 您无法用完全不同的 URL 替换请求 URL
出现这些情况的一个常见情况是,当您尝试使用某些需要 OAuth 或 SSO 工作流的第 3 方端点时,该工作流不打算从前端代码中使用。
在这种情况下——实际上,在所有情况下——必须认识到,对预检的响应必须来自前端代码向其发送请求的同一来源。
因此,即使您创建了一个您控制的 server-side 代理:
- 如果您的浏览器向您的代理发送预检
OPTIONS
请求。 - 您已将代理配置为仅将请求重定向到第 3 方端点。
- 因此,您的前端最终会直接从该第 3 方端点接收响应。
...然后预检将失败。
在这种情况下,最终您唯一的选择是:确保预检不只是重定向到第 3 方端点,而是您自己的 server-side(代理)代码接收来自该端点的响应,消耗它,然后将自己的响应发送回您的前端代码。
当您尝试将 https 服务调用为 http 时,有时会发生这种情况,例如,当您对以下内容执行请求时:
应该是:
'https://example.com/api/v2/tickets'
首先,确保你在 headers
中有 "Access-Control-Allow-Origin": "*"然后只需删除 url
末尾的“/”例如变化
url: "https://facebook/api/login/"
进入
url: "https://facebook/api/login" (without '/')
在我的例子中,我不必将请求 header 设置为具有“Access-Control-Allow-Origin”:“*”。 url 必须以“/”结尾