Es gibt keine Möglichkeit, es von den neuesten Webbrowsern zu unterscheiden.
W3C-Spezifikation:
In den folgenden Schritten wird beschrieben, was Benutzeragenten für eine einfache abgangsübergreifende Anforderung tun müssen :
Wenden Sie die Schritte zum Erstellen einer Anfrage an und beachten Sie die folgenden Anforderungsregeln, während Sie die Anfrage stellen.
Wenn das manuelle Umleitungsflag nicht gesetzt ist und die Antwort den HTTP-Statuscode 301, 302, 303, 307 oder 308 hat,
wenden Sie die Umleitungsschritte an.
Wenn der Endbenutzer die Anforderung abbricht,
wenden Sie die Abbruchschritte an.
Wenn ein Netzwerkfehler vorliegt
Bei DNS-Fehlern, TLS-Aushandlungsfehlern oder anderen Arten von Netzwerkfehlern wenden Sie die Netzwerkfehlerschritte an . Fordern Sie keine Endbenutzerinteraktion an.
Hinweis: Dies schließt keine HTTP-Antworten ein, die auf einen Fehlertyp hinweisen, z. B. den HTTP-Statuscode 410.
Andernfalls führen
Sie eine Überprüfung der gemeinsamen Nutzung von Ressourcen durch. Wenn es fehlschlägt, wenden Sie die Netzwerkfehlerschritte an. Andernfalls beenden Sie diesen Algorithmus, wenn er pass zurückgibt, und setzen Sie den Status der Cross-Origin-Anforderung auf Erfolg. Beenden Sie die Anfrage nicht.
Wie Sie lesen können, enthalten Netzwerkfehler keine HTTP-Antwort, die Fehler enthält. Aus diesem Grund erhalten Sie immer 0 als Statuscode und "" als Fehler.
Quelle
Hinweis : Die folgenden Beispiele wurden mit Google Chrome Version 43.0.2357.130 und in einer Umgebung erstellt, die ich zum Emulieren von OP One erstellt habe. Der Code für die Einrichtung befindet sich am Ende der Antwort.
Ich dachte, dass ein Ansatz, um dies zu umgehen, eine sekundäre Anfrage über HTTP anstelle von HTTPS als Diese Antwort stellen würde, aber ich habe mich daran erinnert, dass dies nicht möglich ist, da neuere Versionen von Browsern gemischte Inhalte blockieren.
Das bedeutet, dass der Webbrowser keine Anforderung über HTTP zulässt, wenn Sie HTTPS verwenden und umgekehrt.
Dies ist seit einigen Jahren so, aber ältere Webbrowser-Versionen wie Mozilla Firefox darunter, Version 23, erlauben dies.
Beweise dafür:
Wenn Sie eine HTTP-Anfrage über HTTPS stellen, verwenden Sie die Web Broser-Konsole
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();
führt zu folgendem Fehler:
Gemischter Inhalt: Die Seite unter ' https: // localhost: 8000 / ' wurde über HTTPS geladen, forderte jedoch einen unsicheren XMLHttpRequest-Endpunkt ' http: // localhost: 8001 / ' an. Diese Anfrage wurde blockiert. Der Inhalt muss über HTTPS bereitgestellt werden.
Der gleiche Fehler wird in der Browserkonsole angezeigt, wenn Sie versuchen, dies auf andere Weise als durch Hinzufügen eines Iframes zu tun.
<iframe src="http://localhost:8001"></iframe>
Die Verwendung der Socket-Verbindung wurde ebenfalls als Antwort veröffentlicht. Ich war mir ziemlich sicher, dass das Ergebnis gleich / ähnlich sein wird, aber ich habe es versucht.
Der Versuch, eine Socket-Verbindung vom Web Broswer mithilfe von HTTPS zu einem nicht sicheren Socket-Endpunkt zu öffnen, führt zu Fehlern mit gemischtem Inhalt.
new WebSocket("ws://localhost:8001", "protocolOne");
1) Gemischter Inhalt: Die Seite unter ' https: // localhost: 8000 / ' wurde über HTTPS geladen, es wurde jedoch versucht, eine Verbindung zum unsicheren WebSocket-Endpunkt 'ws: // localhost: 8001 /' herzustellen. Diese Anfrage wurde blockiert. Dieser Endpunkt muss über WSS verfügbar sein.
2) Nicht erfasste DOME-Ausnahme: Fehler beim Erstellen von 'WebSocket': Eine unsichere WebSocket-Verbindung kann möglicherweise nicht von einer über HTTPS geladenen Seite initiiert werden.
Dann habe ich auch versucht, eine Verbindung zu einem WSS-Endpunkt herzustellen. Sehen Sie, ob ich Informationen zu Netzwerkverbindungsfehlern lesen kann:
var exampleSocket = new WebSocket("wss://localhost:8001", "protocolOne");
exampleSocket.onerror = function(e) {
console.log(e);
}
Das Ausführen des obigen Snippets bei ausgeschaltetem Server führt zu:
WebSocket-Verbindung zu 'wss: // localhost: 8001 /' fehlgeschlagen: Fehler beim Verbindungsaufbau: net :: ERR_CONNECTION_REFUSED
Ausführen des obigen Snippets bei eingeschaltetem Server
WebSocket-Verbindung zu 'wss: // localhost: 8001 /' fehlgeschlagen: Der Handshake zum Öffnen von WebSocket wurde abgebrochen
Aber auch hier hat der Fehler, dass die "Fehlerfunktion" an die Konsole ausgegeben wird, keinen Tipp, um einen Fehler vom anderen zu unterscheiden.
Die Verwendung eines Proxys, wie in dieser Antwort vorgeschlagen, könnte funktionieren, jedoch nur, wenn der "Ziel" -Server öffentlichen Zugriff hat.
Dies war hier nicht der Fall. Der Versuch, einen Proxy in diesem Szenario zu implementieren, führt uns zu demselben Problem.
Code zum Erstellen des HTTPS-Servers von Node.js :
Ich habe zwei Nodejs HTTPS-Server erstellt, die selbstsignierte Zertifikate verwenden:
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);
applicationServer.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);
Damit es funktioniert, müssen Nodejs installiert sein. Für jeden Server müssen separate Zertifikate generiert und entsprechend in den Ordnern certs und certs2 gespeichert werden.
Um Run führen Sie es einfach node applicationServer.js
und node targetServer.js
in einem Terminal (ubuntu Beispiel).