由于 Chrome 中缺少预检请求而被阻止的 HTTP 重定向
Posted
技术标签:
【中文标题】由于 Chrome 中缺少预检请求而被阻止的 HTTP 重定向【英文标题】:Blocked HTTP redirect due to missing preflight request in Chrome 【发布时间】:2017-08-25 11:20:58 【问题描述】:我们目前正在构建一个支持 RESTful API 的 Angular 应用程序。该应用程序尝试使用以下请求 URL 获取用户信息:http://example.com:1337/api/users/1
。此资源以 HTTP 301(永久移动)响应并设置资源已移动到的位置标头,例如Location=http://another-hostname.com:8088/new/users/1
。
Angular 的 HTTP 客户端或者浏览器会自动处理这个响应并重定向到这个新位置。
遗憾的是,在 Chrome 中我们收到以下错误消息:
XMLHttpRequest cannot load http://example.com:1337/api/users/1. Redirect from 'http://example.com:1337/api/users/1' to 'http://another-hostname.com:8088/new/users/1' has been blocked by CORS policy: Request requires preflight, which is disallowed to follow cross-origin redirect.
Chrome 在调用 GET 到新资源之前会跳过预检请求 (CORS)。我们用 Firefox 对此进行了测试,它运行良好。 Firefox 发出新的预检请求,之后的 GET 请求将被成功处理。
所以,我想知道这里的正确行为是什么。有没有人有过 30 倍响应的类似经历?
是否有可能禁用自动浏览器(或 Angular HTTP 客户端)重定向处理?这样我们就可以使用全新的this.http.get(...)
手动处理新的 GET。
感谢您的建议,
迈克尔
【问题讨论】:
您是否尝试过创建自定义 XHRBackend 服务来处理 HTTP 30X 重定向?我只是不确定它是否在 30X 响应时被调用,但如果是,你可以在那里解决问题。 【参考方案1】:Chrome 在调用 GET 到新资源之前会跳过预检请求 (CORS)。我们用 Firefox 对此进行了测试,并且运行良好。 Firefox 发出新的预检请求,之后的 GET 请求将被成功处理。
您可以在此处找到有关此问题的讨论以及其他解决方法以及指向 W3C CORS 建议的相应部分的链接:https://***.com/a/39728229/4282127。
Chrome 自 57 版起应支持重定向 (3xx) 时的预检请求。因此,更新到最新的 Chrome 版本应该至少可以解决丢失预检请求的问题。
【讨论】:
我已经更新了我的浏览器...... Chrome 57 确实根据最新的 CORS 规范处理了重定向的预检请求。【参考方案2】:是否有可能禁用自动浏览器(或 Angular HTTP 客户端)重定向处理?
XMLHttpRequest(以及 Angular 的 $http 因此)没有办法。 fetch()
中提供了这样的选项,它还不是跨浏览器。
但是有一个解决方法:
通过特殊的初步确定最终请求目的地 请求(通过检查 XHR.responseURL)。这应该是一个简单请求:只有 GET/POST/HEAD 并且只有 simple headers — 这样它就不会产生预检.
向该目的地提出“真实”请求。
这里的正确行为是什么
跨站重定向最初是被禁止的,但现在 (since 4 Aug 2016) 是允许的——但大多数浏览器还没有实现这一变化。
这在MDN https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Preflighted_requests_and_redirects中有非常清楚的解释
【讨论】:
以上是关于由于 Chrome 中缺少预检请求而被阻止的 HTTP 重定向的主要内容,如果未能解决你的问题,请参考以下文章
从源 xxxx 访问 XMLHttpRequest ' 被 CORS 策略阻止:对预检的响应。预检请求不允许重定向