gpt4 book ai didi

javascript - 确定 ajax 调用是否由于不安全的响应或连接被拒绝而失败

转载 作者:IT王子 更新时间:2023-10-29 02:40:02 26 4
gpt4 key购买 nike

我做了很多研究,但找不到处理这个问题的方法。我正在尝试执行从 https 服务器到运行带有自定义自签名证书的码头的 locahost https 服务器的 jQuery ajax 调用。我的问题是我无法确定响应是拒绝连接还是不安全响应(由于缺少证书接受)。有没有办法确定这两种情况之间的区别? responseTextstatusCode 在这两种情况下始终相同,即使在 chrome 控制台中我可以看到不同之处:

net::ERR_INSECURE_RESPONSE
net::ERR_CONNECTION_REFUSED
对于这两种情况,

responseText 始终为“”,statusCode 始终为“0”。

我的问题是,如何确定 jQuery ajax 调用失败是由于 ERR_INSECURE_RESPONSE 还是由于 ERR_CONNECTION_REFUSED

接受证书后一切正常,但我想知道本地服务器是否已关闭,或者它已启动并正在运行但证书尚未被接受。

$.ajax({
type: 'GET',
url: "https://localhost/custom/server/",
dataType: "json",
async: true,
success: function (response) {
//do something
},
error: function (xhr, textStatus, errorThrown) {
console.log(xhr, textStatus, errorThrown); //always the same for refused and insecure responses.
}
});

enter image description here

即使手动执行请求,我也会得到相同的结果:

var request = new XMLHttpRequest();
request.open('GET', "https://localhost/custom/server/", true);
request.onload = function () {
console.log(request.responseText);
};
request.onerror = function () {
console.log(request.responseText);
};
request.send();

最佳答案

无法将其与最新的 Web 浏览器区分开来。

W3C 规范:

The steps below describe what user agents must do for a simple cross-origin request:

Apply the make a request steps and observe the request rules below while making the request.

If the manual redirect flag is unset and the response has an HTTP status code of 301, 302, 303, 307, or 308 Apply the redirect steps.

If the end user cancels the request Apply the abort steps.

If there is a network error In case of DNS errors, TLS negotiation failure, or other type of network errors, apply the network error steps. Do not request any kind of end user interaction.

Note: This does not include HTTP responses that indicate some type of error, such as HTTP status code 410.

Otherwise Perform a resource sharing check. If it returns fail, apply the network error steps. Otherwise, if it returns pass, terminate this algorithm and set the cross-origin request status to success. Do not actually terminate the request.

如您所见,网络错误不包括包含错误的 HTTP 响应,这就是为什么您将始终获得 0 作为状态代码,而“”作为错误。

Source


注意:以下示例是使用 Google Chrome 版本 43.0.2357.130 和我创建的用于模拟 OP one 的环境制作的。设置它的代码在答案的底部。


我认为解决此问题的方法是通过 HTTP 而不是 HTTPS 发出二次请求 This answer但我记得这是不可能的,因为较新版本的浏览器会阻止混合内容。

这意味着如果您使用 HTTPS,Web 浏览器将不允许通过 HTTP 请求,反之亦然。

从几年前开始就是这样,但较旧的 Web 浏览器版本(例如低于其版本 23 的 Mozilla Firefox)允许这样做。

关于它的证据:

从 HTTPS 使用 Web Broser 控制台发出 HTTP 请求

var request = new XMLHttpRequest();
request.open('GET', "http://localhost:8001", true);
request.onload = function () {
console.log(request.responseText);
};
request.onerror = function () {
console.log(request.responseText);
};
request.send();

会导致以下错误:

Mixed Content: The page at 'https://localhost:8000/' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint 'http://localhost:8001/'. This request has been blocked; the content must be served over HTTPS.

如果您尝试以添加 Iframe 的其他方式执行此操作,浏览器控制台中将出现相同的错误。

<iframe src="http://localhost:8001"></iframe>

使用Socket连接也是Posted as an answer ,我很确定结果会相同/相似,但我试过了。

尝试使用 HTTPS 打开从 Web Broswer 到非安全套接字端点的套接字连接将导致混合内容错误。

new WebSocket("ws://localhost:8001", "protocolOne");

1) Mixed Content: The page at 'https://localhost:8000/' was loaded over HTTPS, but attempted to connect to the insecure WebSocket endpoint 'ws://localhost:8001/'. This request has been blocked; this endpoint must be available over WSS.

2) Uncaught DOMException: Failed to construct 'WebSocket': An insecure WebSocket connection may not be initiated from a page loaded over HTTPS.

然后我尝试连接到 wss 端点,看看是否可以阅读有关网络连接错误的一些信息:

var exampleSocket = new WebSocket("wss://localhost:8001", "protocolOne");
exampleSocket.onerror = function(e) {
console.log(e);
}

在关闭服务器的情况下执行上面的代码片段会导致:

WebSocket connection to 'wss://localhost:8001/' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED

在服务器打开的情况下执行上面的代码片段

WebSocket connection to 'wss://localhost:8001/' failed: WebSocket opening handshake was canceled

但同样,“onerror function”输出到控制台的错误没有任何提示来区分一个错误和另一个错误。


使用代理作为 this answer suggest可以工作,但前提是“目标”服务器具有公共(public)访问权限。

这里不是这种情况,因此尝试在这种情况下实现代理将导致我们遇到同样的问题。

创建 Node.js HTTPS 服务器的代码:

我创建了两个使用自签名证书的 Nodejs HTTPS 服务器:

目标服务器.js:

var https = require('https');
var fs = require('fs');

var options = {
key: fs.readFileSync('./certs2/key.pem'),
cert: fs.readFileSync('./certs2/key-cert.pem')
};

https.createServer(options, function (req, res) {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
res.writeHead(200);
res.end("hello world\n");
}).listen(8001);

应用服务器.js:

var https = require('https');
var fs = require('fs');

var options = {
key: fs.readFileSync('./certs/key.pem'),
cert: fs.readFileSync('./certs/key-cert.pem')
};

https.createServer(options, function (req, res) {
res.writeHead(200);
res.end("hello world\n");
}).listen(8000);

要使其正常工作,您需要安装 Nodejs,需要为每个服务器生成单独的证书并将其相应地存储在文件夹 certs 和 certs2 中。

要运行它,只需在终端(ubuntu 示例)中执行 node applicationServer.jsnode targetServer.js

关于javascript - 确定 ajax 调用是否由于不安全的响应或连接被拒绝而失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31058764/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com