jQuery 对不受信任(自签名)HTTPS 的 AJAX 调用无声无息地失败
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4565772/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
AJAX calls to untrusted (self-signed) HTTPS fail silently
提问by Coderer
I want to make AJAX calls to a secure server that uses a self-signed certificate. In the environment where my app is being used, this is fine -- I can provide the CA cert to users and have them install it before using the app. However, sometimes, a user tries to visit the app before installing the certs. In these cases, the app silently fails -- at least in Firefox (most common case of the problem), it appears that the call silently dies, without even firing off the error handler. FWIW, if the user visits an actual pageon the server, they get a cert warning.
我想对使用自签名证书的安全服务器进行 AJAX 调用。在使用我的应用程序的环境中,这很好——我可以向用户提供 CA 证书并让他们在使用应用程序之前安装它。但是,有时,用户会在安装证书之前尝试访问该应用程序。在这些情况下,应用程序会默默地失败——至少在 Firefox 中(问题的最常见情况),似乎调用会默默地终止,甚至没有触发错误处理程序。FWIW,如果用户访问服务器上的实际页面,他们会收到证书警告。
I could hack in a workaround -- say, make a heartbeat/ping request and set up a watchdog timer to see if the server responds in time -- but that seems, well, hacky. I'd prefer to be able to test the connection ahead of time. What's the "right" way to make sure the server you want to talk to has a trusted cert from within Javascript? If it makes any difference, I'm doing my AJAX requests via JQuery.
我可以通过一种变通方法来破解——比如说,发出一个心跳/ping 请求并设置一个看门狗计时器来查看服务器是否及时响应——但这似乎很糟糕。我希望能够提前测试连接。确保您要与之交谈的服务器在 Javascript 中拥有受信任的证书的“正确”方法是什么?如果它有任何区别,我正在通过 JQuery 执行我的 AJAX 请求。
UPDATE: There's an awesome punchline here. Turns out, AJAX was not the problem at all. I was sure based on the symptoms that it was related to the self-signed certs, but the lack of AJAX error was disturbing, esp. given the spec linked to in the answer below. Another team member nailed it: the AJAX error handlers weren't firing off because JQuery was never loaded! We were including JQuery from another subdomain of our site, also hosted on HTTPS -- and users had added exceptions for ourService.example.com but not js.example.com. Apparently if you point a <script>
tag at non-trusted secure connection, thatfails silently as well.
更新:这里有一个很棒的妙语。事实证明,AJAX 根本不是问题。根据症状,我确信它与自签名证书有关,但是缺少 AJAX 错误令人不安,尤其是。鉴于在下面的答案中链接到的规范。另一位团队成员指出:AJAX 错误处理程序没有触发,因为JQuery 从未加载过!我们从我们网站的另一个子域中包含了 JQuery,该子域也托管在 HTTPS 上——用户为 ourService.example.com 添加了例外,但没有为 js.example.com 添加例外。显然,如果您将<script>
标签指向不受信任的安全连接,那么它也会以静默方式失败。
{/headdesk}
{/办公桌}
采纳答案by Seldaek
XMLHttpRequests (AJAX requests) are only permitted on same-origin servers. That means the scheme://host:port part of the target URL has to match that of the current document. According to the spec, you shouldn't even be allowed to make a request on the SSL URL from the non-SSL one.
XMLHttpRequests(AJAX 请求)只允许在同源服务器上。这意味着目标 URL 的 scheme://host:port 部分必须与当前文档的匹配。根据规范,您甚至不应该被允许从非 SSL URL 向 SSL URL 发出请求。
The less hackish solution that I see is that you just force-redirect all users to the SSL site. That way they will be forced to see the certificate warning before any AJAX request can be made.
我看到的不那么骇人听闻的解决方案是您只需将所有用户强制重定向到 SSL 站点。这样,他们将被迫在发出任何 AJAX 请求之前看到证书警告。
Note: The spec also says that in case of TLS handshake failure (which I assume this case falls under, in a way) it should throw a NETWORK_ERR (code 19) exception. You could try to catch the exception when initiating the AJAX request. Refer to the specon error handling for more details.
注意:规范还说,在 TLS 握手失败的情况下(我认为这种情况在某种程度上属于这种情况)它应该抛出一个 NETWORK_ERR(代码 19)异常。您可以尝试在启动 AJAX 请求时捕获异常。有关更多详细信息,请参阅错误处理规范。