【问题标题】:How to prevent Chrome to redirecting AJAX requests to HTTPS?如何防止 Chrome 将 AJAX 请求重定向到 HTTPS?
【发布时间】:2014-10-09 04:14:29
【问题描述】:

我的 AngularJS 应用程序正在对我们的服务(由 Jetty 提供支持)执行许多 AJAX 请求。出于某种原因,仅某些用户会出现以下错误,并在被要求清除浏览器缓存时消失。这仅在 Google Chrome 上发生

我正在 www.domain.com 上尝试请求 api.domain.com。

XMLHttpRequest 无法加载 http://api.domain.com/my-service。这 请求被重定向到“https://api.domain.com/my-service”,其中 对于需要预检的跨域请求是不允许的。 /我的当前页面

请注意,Chrome 正在尝试将服务从 HTTP 重定向到 HTTPS。我的网站可以通过 HTTP 或 HTTPS 访问

这是 chrome://net-internals/#events 输出:

1523417: URL_REQUEST
http://api.domain.com/my-service
Start Time: 2014-08-15 14:17:39.809

t=5984 [st= 0] +REQUEST_ALIVE  [dt=26]
t=5984 [st= 0]   +URL_REQUEST_DELEGATE  [dt=0]
t=5984 [st= 0]      DELEGATE_INFO  [dt=0]
                    --> delegate_info = "extension AdBlock"
t=5984 [st= 0]      DELEGATE_INFO  [dt=0]
                    --> delegate_info = "extension AdBlock"
t=5984 [st= 0]   -URL_REQUEST_DELEGATE
t=5984 [st= 0]   +URL_REQUEST_START_JOB  [dt=26]
                  --> load_flags = 143540480 (DO_NOT_SAVE_COOKIES | DO_NOT_SEND_AUTH_DATA | DO_NOT_SEND_COOKIES | ENABLE_LOAD_TIMING | MAYBE_USER_GESTURE | REPORT_RAW_HEADERS | VERIFY_EV_CERT)
                  --> method = "OPTIONS"
                  --> priority = "LOW"
                  --> url = "http://api.domain.com/my-service"
t=5984 [st= 0]      URL_REQUEST_REDIRECT_JOB
                    --> reason = "HSTS"
t=5985 [st= 1]     +URL_REQUEST_DELEGATE  [dt=25]
t=5985 [st= 1]        DELEGATE_INFO  [dt=25]
                      --> delegate_info = "AsyncResourceHandler"
t=6010 [st=26]     -URL_REQUEST_DELEGATE
t=6010 [st=26]      CANCELLED
t=6010 [st=26]   -URL_REQUEST_START_JOB
                  --> net_error = -3 (ERR_ABORTED)
t=6010 [st=26]    URL_REQUEST_DELEGATE  [dt=0]
t=6010 [st=26] -REQUEST_ALIVE

知道为什么 Chrome 会强制进行这样的重定向吗?我在网络选项卡中看不到任何错误,该请求没有返回任何内容。

更多信息:

这是正常运行的 Chrome 浏览器上的响应标头。

Access-Control-Allow-Credentials:true
Access-Control-Allow-Headers:X-Requested-With, authorization, content-type, X-CSRF-Token
Access-Control-Allow-Methods:GET, POST, HEAD, PUT, OPTIONS
Access-Control-Allow-Origin:http://api.domain.com
Content-Length:0
Server:Jetty(8.y.z-SNAPSHOT)

【问题讨论】:

    标签: google-chrome xmlhttprequest cors preflight


    【解决方案1】:

    这可能是由无处不在的 HTTPS 等扩展或严格传输安全 (HSTS) 引起的。

    这些因素不在您的控制范围内,要解决它,您需要修改服务器端 API 端点以提供 CORS 响应标头,例如:

    Access-Control-Allow-Origin: http://api.domain.com
    

    ... 或者只是在侧面强制执行 https。那么你就不用担心 http/https 来源违规了。作为奖励,https 最近已成为您网站在 Google 上排名的积极因素之一。


    问题中的日志清楚地表明,HSTS 是罪魁祸首。 Chrome 的 HSTS 实现目前无法正常处理跨域请求 (crbug.com/387198)。网站所有者解决此错误的唯一方法是强制执行横向 https,并通过 https 访问 API。

    如果您想重现该错误,请访问chrome://net-internals/#hsts 并通过第一个输入框(“添加域”)将域添加到 HSTS 列表中。然后,在重现错误后,通过第二个输入框(“删除域”)从 HSTS 列表中删除域。此方法也是用户解决该错误的一种方法。毕竟,如果该域从 HSTS 列表中删除,则不再有 HSTS 重定向。

    什么是 HSTS?
    服务器在其任何 https 响应中发送 Strict-Transport-Security 标头后激活 HSTS。浏览器收到这个header一次后,会强制网页上的所有资源都通过https请求。有关详细信息,请参阅 http://chromium.org/stshttp://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security

    由于此错误仅发生在您的某些用户中,因此很可能是由浏览器扩展或 API 域中的某些页面引起的,该页面以 STS 标头进行响应。

    【讨论】:

    • 它可以在我的机器上运行,但不能在我同事的 Chrome 上运行,我已经编辑了问题以在它运行时显示来自服务器的响应。
    • 更好的评论:它可以在我的机器上运行,但不能在我同事的 Chrome 上运行(但他可以以标准 HTTP 模式浏览​​网站),我已经编辑了问题以显示服务器的响应作品。谢谢,我会考虑迁移到全 HTTPS 网站。
    • @vincentp 您问题中的日志清楚地表明,HSTS 是罪魁祸首。 Chrome 的 HSTS 实现目前不能正确支持 CORS。我已在 7 周前向 Chromium 提交了针对该错误的补丁,但该补丁仍在审核中:codereview.chromium.org/348253002。在该补丁被接受之前,您不能将 CORS 与 HSTS 结合使用。
    • 非常感谢您的帮助。我以前从未听说过 HSTS。我试图了解事件链并理解为什么 Chrome 会认为这个域/查询应该通过 HTTPS 完成。这是在 Web 服务器级别为域定义的吗?我们有一个由 Nginx 运行的负载均衡器,它负责处理 SSL 证书和其他事情,它可以在这里吗?
    • 再次感谢,我会深入研究我们的配置。
    猜你喜欢
    • 2015-03-02
    • 1970-01-01
    • 2018-09-15
    • 2018-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-04
    相关资源
    最近更新 更多