如何解决“预检请求无效(重定向)”或“不允许对预检请求进行重定向”的问题?

83
我按照以下步骤设置了服务器以启用CORS: https://learn.microsoft.com/en-us/aspnet/web-api/overview/security/enabling-cross-origin-requests-in-web-api 但是现在在浏览器的开发控制台中,我看到下面的错误信息:

XMLHttpRequest无法加载 https://serveraddress/abc。预请求的响应无效(重定向)

你知道我该怎么办才能解决它吗? 我正在HTTPS中进行CORS请求。 我认为这导致了'preflight is invalid (redirect)'错误。 但我不知道为什么或者是什么在重定向OPTIONS请求。
谢谢。
6个回答

175

简短回答:确保您的代码中请求URL不缺少尾随斜杠。

缺少尾随斜杠是导致问题的最常见原因。

但这不是唯一的原因 - 只是最常见的原因。请继续阅读以获取更多详细信息。

当您看到此错误时,这意味着您的代码会触发浏览器发送CORS预检OPTIONS请求,而服务器则响应一个3xx重定向。为了避免出现该错误,您的请求需要获得一个2xx成功响应。

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

至于在这种情况下发生了什么,重要的是要知道,如果:

  • 请求方法是除GETHEADPOST之外的任何其他方法
  • 您设置了自定义请求头而不是AcceptAccept-LanguageContent-LanguageContent-TypeDPRDownlinkSave-DataViewport-WidthWidth
  • Content-Type请求头的值不是application/x-www-form-urlencodedmultipart/form-datatext/plain

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

  1. 检查响应中OPTIONS请求的Location响应头中的URL。
  2. 更改您的代码,直接向该其他URL发出请求。
URL之间的区别可能只是路径中末尾斜杠这样简单的东西 - 例如,您可能需要更改代码中的URL以添加末尾斜杠,例如:http://localhost/api/auth/login/(注意末尾斜杠),而不是http://localhost/api/auth/login(没有末尾斜杠)- 或者您可能需要删除末尾斜杠。您可以使用浏览器开发工具中的网络选项卡来检查OPTIONS请求的响应,并在Location响应标头的值中找到重定向URL。
但是,在某些情况下,所有以下内容都是真实的: - 您无法避免预检请求OPTIONS - 您无法对请求URL进行任何调整 - 您无法用完全不同的URL替换请求URL
具有这些条件的常见情况是,当您尝试使用某些第三方端点进行工作时,该端点需要OAuth或SSO工作流程,这些工作流程不适用于前端代码。
在这种情况下 - 实际上在所有情况下 - 必须认识到的关键是,对预检的响应必须来自与您的前端代码发送请求的同一起源。
因此,即使您创建了自己控制的服务器端代理: 1. 如果您的浏览器向代理发送预检OPTIONS请求。 2. 您已配置代理以将请求重定向到第三方端点。 3. 因此,您的前端最终直接从该第三方端点接收响应。
然后预检将失败。在这种情况下,您的唯一选择是:确保预检不仅被重定向到第三方端点,而且您自己的服务器端(代理)代码接收来自该端点的响应,使用它,然后向您的前端代码发送自己的响应。

2
谢谢您的回答。我会遵循您的建议。我的应用程序需要向服务器发送Content-Type application/json,这就是触发预检的原因。而且我不能改变它。 - n179911
7
我知道这已经过去了几年,但今天这帮了我一把。我的问题是缺少一个斜杠。谢谢! - ellaRT
3
好的、有用的信息永远不会过时。 - Sergio A.
2
我决定从所有的URL中彻底删除尾部斜杠。由于这个预检CORS错误,我遭受了相当多的痛苦。我发现有些页面有这个错误,而其他页面没有。这是一个可怕的经历,持续了好几周! - andromeda
2
请求头的Content-Type值不是[...]。这并不像(没有双关语)那么简单:https://twitter.com/jub0bs/status/1432025056234835980 - jub0bs
显示剩余11条评论

42
有时候,当您尝试以HTTP方式调用HTTPS服务时,例如在以下请求上执行请求时,会出现此问题:

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

应该改为:

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


15
首先,请确保您的标头中包含“Access-Control-Allow-Origin”:“*”
然后只需删除URL末尾的“/”
例如:更改
url: "https://facebook/api/login/"

进入

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

或者反之亦然


2
仅当您希望您的端点对所有人开放时才执行此操作。您可以通过添加以下内容来允许您自己的域名(和子域名): SetEnvIf Origin "^(.*.domain.com)$" ORIGIN_SUB_DOMAIN=$1 Header set Access-Control-Allow-Origin "%{ORIGIN_SUB_DOMAIN}e" env=ORIGIN_SUB_DOMAIN - Wijnand
1
"Access-Control-Allow-Origin": "*" 这在生产环境中可能存在安全风险,但在开发过程中是可以接受的。 - Md. A. Apu
这对我有点用,现在不是404错误了,而是500错误。 - ERJAN

5
在我的情况下,我不需要设置请求头来拥有 "Access-Control-Allow-Origin": "*"。URL必须以 "/" 结尾。

1

在我的情况下,我解决了这个预检请求,只需在 API 的末尾加上一个斜杠 (/)。

#django #reactJs


目前你的回答不够清晰,请编辑并添加更多细节,以帮助其他人理解它如何回答问题。你可以在帮助中心找到有关如何撰写好答案的更多信息。 - Community
这并没有回答问题。一旦您拥有足够的声望,您将能够评论任何帖子;相反,提供不需要询问者澄清的答案。- 来自审核 - GuedesBF

-1

服务器对CORS请求进行了响应,将其重定向到与原始请求不同源的URL上,这在CORS请求期间是不允许的。

例如,如果请求页面https://service.tld/fetchdata,并且HTTP响应为“301 Moved Permanently”,“307 Temporary Redirect”或“308 Permanent Redirect”,其中Location为https://anotherservice.net/getdata,则CORS请求将以此方式失败。

要解决问题,请更新您的代码以使用重定向报告的新URL,从而避免重定向。服务器对CORS请求进行了响应,将其重定向到与原始请求不同源的URL上,这在CORS请求期间是不允许的。

例如,如果请求页面https://service.tld/fetchdata,并且HTTP响应是“301 Moved Permanently”,“307 Temporary Redirect”或“308 Permanent Redirect”,其中Location为https://anotherservice.net/getdata,则CORS请求将以此方式失败。
要解决问题,请更新您的代码以使用重定向报告的新URL,从而避免重定向。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接