There is no way to differentiate it from newest Web Browsers.
W3C Specification:
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个
应用重定向步骤.
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个
执行资源共享判断.如果返回失败,请应用网络错误步骤.否则,如果返回PASS,则终止该算法,并将跨域请求状态设置为SUCCESS.请不要实际终止请求.
As you can read, network errors does not include HTTP response that include errors, that is why you will get always 0 as status code, and "" as error.个
Source
Note: The following examples were made using Google Chrome Version 43.0.2357.130 and against an environment that I've created to emulate OP one. Code to the set it up is at the bottom of the answer.
I though that an approach To work around this would be make a secondary request over HTTP instead of HTTPS as This answer but I've remembered that is not possible due that newer versions of browsers block mixed content.
这意味着,如果您使用HTTPS,Web浏览器将不允许通过HTTP进行请求,反之亦然.
这在几年前就是这样了,但是更老的Web浏览器版本,如下面的Mozilla Firefox版本23允许这样做.
Evidence about it:
Making a HTTP request from HTTPS usign Web Broser console
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();
将导致以下错误:
混合内容:"https://localhost:8000/"处的页面是通过HTTPS加载的,但请求了不安全的XMLHttpRequest终结点"http://localhost:8001/".此请求已被阻止;内容必须通过HTTPS提供.
Same error will appear in the browser console if you try to do this in other ways as adding an Iframe.
<iframe src="http://localhost:8001"></iframe>
使用Socket connection也是Posted as an answer,我很确定结果会相同/相似,但我已经try 过了.
Trying to Open a socket connection from the Web Broswer using HTTPS to a non Secure socket endpoint will end in mixed content errors.
new WebSocket("ws://localhost:8001", "protocolOne");
1) 混合内容:"https://localhost:8000/"处的页面通过HTTPS加载,但试图连接到不安全的WebSocket端点"ws://localhost:8001/".此请求已被阻止;此端点必须通过WSS可用.
2) Uncaught DOMException: Failed to construct 'WebSocket': An insecure WebSocket connection may not be initiated from a page loaded over HTTPS.
然后,我也try 连接到wss端点,看看是否可以阅读有关网络连接错误的信息:
var exampleSocket = new WebSocket("wss://localhost:8001", "protocolOne");
exampleSocket.onerror = function(e) {
console.log(e);
}
Executing snippet above with Server turned off results in:
到‘wss://localhost:8001/’的WebSocket连接失败:建立连接时出错:NET::ERR_CONNECTION_REJECTED
Executing snippet above with Server turned On
WebSocket connection to 'wss://localhost:8001/' failed: WebSocket opening handshake was canceled
But again, the error that the "onerror function" output to the console have not any tip to differentiate one error of the other.
使用代理as this answer suggest可以工作,但前提是"目标"服务器具有公共访问权限.
这里的情况并非如此,因此在这种情况下try 实现代理将导致我们遇到同样的问题.
Code to create Node.js HTTPS server:
我创建了两个使用自签名证书的Nodejs HTTPS服务器:
targetServer.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,需要 for each 服务器生成单独的证书,并相应地将其存储在文件夹certs和certs2中.
To Run it just execute node applicationServer.js
and node targetServer.js
in a terminal (ubuntu example).