如何解决“预检无效(重定向)”或“预检请求不允许重定向”

Posted

技术标签:

【中文标题】如何解决“预检无效(重定向)”或“预检请求不允许重定向”【英文标题】:How to resolve 'preflight is invalid (redirect)' or 'redirect is not allowed for a preflight request' 【发布时间】:2022-01-18 15:49:26 【问题描述】:

我已按照此步骤设置我的服务器以启用 CORS。 https://docs.microsoft.com/en-us/aspnet/web-api/overview/security/enabling-cross-origin-requests-in-web-api

但现在在我的浏览器开发控制台中,我看到了以下错误消息:

XMLHttpRequest 无法加载 https://serveraddress/abc。回应 预检无效(重定向)

你知道我能做些什么来解决它吗?我正在 HTTPS 中发出 CORS 请求。我认为这导致“预检无效(重定向)”失败。但我不知道重定向 OPTIONS 请求的原因或内容。

谢谢。

【问题讨论】:

【参考方案1】:

简答:确保代码中的请求 URL 不缺少尾部斜杠。

缺少尾随斜杠问题是问题中引用的错误的最常见原因。

但这不是唯一的原因——只是最常见的原因。继续阅读以了解更多详情。

当您看到此错误时,这意味着您的代码正在触发您的浏览器发送CORS preflight OPTIONS request,并且服务器以3xx 重定向响应。为避免该错误,您的请求需要获得2xx 成功响应。

您可以调整您的代码以避免触发浏览器发送OPTIONS 请求。

就本例中发生的情况而言,重要的是要知道浏览器会在以下情况下进行 CORS 预检:

请求方法不是GETHEADPOST 您设置了除AcceptAccept-LanguageContent-LanguageContent-TypeDPRDownlinkSave-DataViewport-Width 或 @987654338 之外的自定义请求标头 Content-Type 请求标头的值不是application/x-www-form-urlencodedmultipart/form-datatext/plain

如果您无法更改代码以避免浏览器需要进行预检,另一种选择是:

    在对OPTIONS 请求的响应中检查Location 响应标头中的URL。 更改您的代码以直接向其他 URL 发出请求。

网址之间的区别可能很简单,例如路径中的尾部斜杠 - 例如,您可能需要更改代码中的网址以添加尾部斜杠 - 例如,http://localhost/api/auth/login/(请注意尾部斜杠) 而不是 http://localhost/api/auth/login(没有尾部斜杠)——或者您可能需要删除尾部斜杠。

您可以使用浏览器开发工具中的网络窗格来检查对OPTIONS 请求的响应,并在Location 响应标头的值中找到重定向 URL。


但是,在某些情况下,以下所有情况都是正确的:

你无法避免预检OPTIONS 您无法对请求 URL 进行任何调整 您无法将请求 URL 替换为完全不同的 URL

这些情况的常见情况是当您尝试使用某些需要 OAuth 或 SSO 工作流程的第三方端点,而该工作流程不打算从前端代码中使用。

在这种情况下——实际上在所有情况下——必须认识到,对预检的响应必须来自您的前端代码向其发送请求的同一来源。

因此,即使您创建了一个您可以控制的服务器端代理:

    如果您的浏览器向您的代理发送预检OPTIONS 请求。 您已配置代理,使其仅将请求重定向到第 3 方端点。 因此,您的前端最终会直接从该第 3 方端点接收响应。

…那么预检将失败。

在这种情况下,最终您唯一的选择是:确保预检不只是重定向到第 3 方端点,而是您自己的服务器端(代理)代码接收来自该端点的响应,使用它,然后将自己的响应发送回您的前端代码。

【讨论】:

感谢您的回答。我会听从你的建议。我的应用程序需要将 Content-Type application/json 发送到服务器,以便触发预飞行。我无法改变这一点。 我知道已经有好几年了,但今天这对我有帮助。我的问题是缺少尾部斜杠。谢谢! 好的有用的信息永远不会过时。 太棒了,我一直被这个问题困扰,你的回答对我帮助很大! Content-Type 请求标头的值不是 [...] 这不是那么简单(没有双关语):twitter.com/jub0bs/status/1432025056234835980【参考方案2】:

首先,确保标题中有“Access-Control-Allow-Origin”:“*”

然后只需删除 url 末尾的“/”

例如改变

url: "https://facebook/api/login/"

进入

url: "https://facebook/api/login" (without '/')

【讨论】:

仅当您希望您的端点对所有人开放时才执行此操作。您可以通过添加以下内容来允许您自己的域(和子域): SetEnvIf Origin "^(.*\.domain\.com)$" ORIGIN_SUB_DOMAIN=$1 Header set Access-Control-Allow-Origin "%ORIGIN_SUB_DOMAINe " env=ORIGIN_SUB_DOMAIN "Access-Control-Allow-Origin": "*" 这可能是生产中的安全风险,但对于开发来说没关系。【参考方案3】:

就我而言,我不必将请求标头设置为“Access-Control-Allow-Origin”:“*”。网址必须以“/”结尾

【讨论】:

【参考方案4】:

当您尝试将 https 服务调用为 http 时,有时会发生这种情况,例如,当您在以下位置执行请求时:

'http://example.com/api/v2/tickets'

应该是:

'https://example.com/api/v2/tickets'

【讨论】:

以上是关于如何解决“预检无效(重定向)”或“预检请求不允许重定向”的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的 $.ajax 显示“预检无效重定向错误”?

为啥我的 $.ajax 显示“预检无效重定向错误”?

CORS:对预检请求的响应未通过访问控制检查:预检请求不允许重定向

从源 xxxx 访问 XMLHttpRequest ' 被 CORS 策略阻止:对预检的响应。预检请求不允许重定向

ASP.NET Core Web API + Angular 对预检请求的响应未通过访问控制检查:预检请求不允许重定向

使用 CORS 在 AWS S3 存储桶上获取