Ich habe viel recherchiert und konnte keinen Weg finden, damit umzugehen. Ich versuche, einen jQuery-Ajax-Aufruf von einem https-Server an einen lokalen https-Server auszuführen, auf dem Jetty mit einem benutzerdefinierten selbstsignierten Zertifikat ausgeführt wird. Mein Problem ist, dass ich nicht feststellen kann, ob es sich bei der Antwort um eine verweigerte Verbindung oder um eine unsichere Antwort handelt (aufgrund der fehlenden Zertifikatsakzeptanz). Gibt es eine Möglichkeit, den Unterschied zwischen beiden Szenarien zu bestimmen? Die responseText
und statusCode
sind in beiden Fällen immer gleich, obwohl ich in der Chromkonsole einen Unterschied sehe:
net::ERR_INSECURE_RESPONSE
net::ERR_CONNECTION_REFUSED
responseText
ist immer "" und statusCode
ist in beiden Fällen immer "0".
Meine Frage ist, wie kann ich feststellen, ob ein jQuery-Ajax-Aufruf aufgrund ERR_INSECURE_RESPONSE
oder aufgrund von fehlgeschlagen ist ERR_CONNECTION_REFUSED
?
Sobald das Zertifikat akzeptiert wurde, funktioniert alles einwandfrei, aber ich möchte wissen, ob der localhost-Server heruntergefahren oder betriebsbereit ist, aber das Zertifikat noch nicht akzeptiert wurde.
$.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.
}
});
Selbst wenn ich die Anfrage manuell ausführe, erhalte ich das gleiche Ergebnis:
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();
quelle
function (xhr, status, msg) {...
Ich bezweifle, dass sie es tun, aber es lohnt sich, es zu versuchen.Antworten:
Es gibt keine Möglichkeit, es von den neuesten Webbrowsern zu unterscheiden.
W3C-Spezifikation:
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
führt zu folgendem Fehler:
Der gleiche Fehler wird in der Browserkonsole angezeigt, wenn Sie versuchen, dies auf andere Weise als durch Hinzufügen eines Iframes zu tun.
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.
Dann habe ich auch versucht, eine Verbindung zu einem WSS-Endpunkt herzustellen. Sehen Sie, ob ich Informationen zu Netzwerkverbindungsfehlern lesen kann:
Das Ausführen des obigen Snippets bei ausgeschaltetem Server führt zu:
Ausführen des obigen Snippets bei eingeschaltetem Server
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:
applicationServer.js:
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
undnode targetServer.js
in einem Terminal (ubuntu Beispiel).quelle
Ab sofort: Es gibt keine Möglichkeit, dieses Ereignis zwischen Browers zu unterscheiden. Da die Browser kein Ereignis bereitstellen, auf das Entwickler zugreifen können. (Juli 2015)
Diese Antwort versucht lediglich, Ideen für eine mögliche, albiet hacky und unvollständige Lösung zu liefern.
Haftungsausschluss: Diese Antwort ist unvollständig, da sie die Probleme von OP nicht vollständig löst (aufgrund von Cross-Origin-Richtlinien). Die Idee selbst hat jedoch einige Vorteile , die durch Folgendes erweitert werden: @artur grzesiak hier unter Verwendung eines Proxys und eines Ajax .
Nach einigen Recherchen scheint es keine Form der Fehlerprüfung für den Unterschied zwischen verweigerter Verbindung und einer unsicheren Antwort zu geben, zumindest was Javascript betrifft, das eine Antwort auf den Unterschied zwischen beiden liefert.
Der allgemeine Konsens meiner Forschung besteht darin, dass SSL-Zertifikate vom Browser verarbeitet werden. Bis ein selbstsigniertes Zertifikat vom Benutzer akzeptiert wird, sperrt der Browser alle Anforderungen, einschließlich der Anforderungen für einen Statuscode. Der Browser könnte (falls codiert) seinen eigenen Statuscode für eine unsichere Antwort zurücksenden, aber das hilft nichts, und selbst dann hätten Sie Probleme mit der Browserkompatibilität (Chrome / Firefox / IE mit unterschiedlichen Standards). .. Noch einmal)
Könnten Sie nicht eine Standard-HTTP-Anfrage wie diese stellen, da Ihre ursprüngliche Frage darin bestand, den Status Ihres Servers zwischen dem Betrieb und einem nicht akzeptierten Zertifikat zu überprüfen?
Zugegeben, dies erfordert eine zusätzliche Anforderung zum Überprüfen der Serverkonnektivität, sollte jedoch die Aufgabe durch den Eliminierungsprozess erledigen. Fühlt sich trotzdem hackig an und ich bin kein großer Fan der doppelten Anfrage.
quelle
@ Schultzies Antwort ist ziemlich nah, aber
http
im Allgemeinen funktioniert siehttps
in der Browser-Umgebung eindeutig nicht .Sie können jedoch einen Zwischenserver (Proxy) verwenden, um die Anforderung in Ihrem Namen zu stellen. Der Proxy sollte entweder das Weiterleiten von
http
Anforderungen vomhttps
Ursprung oder das Laden von Inhalten von selbstsignierten Ursprüngen ermöglichen .Ein eigener Server mit ordnungsgemäßem Zertifikat ist in Ihrem Fall wahrscheinlich ein Overkill - da Sie diese Einstellung anstelle des Computers mit selbstsigniertem Zertifikat verwenden könnten -, aber es gibt viele anonyme offene Proxy-Dienste .
Zwei Ansätze, die mir in den Sinn kommen, sind:
.parentWindow
. Wenn Ihr Fenster eine Nachricht erhalten hat, können Sie sicher sein, dass der Server ausgeführt wird (oder genauer gesagt einen Bruchteil einer Sekunde zuvor ausgeführt wurde).Wenn Sie nur an Ihrer lokalen Umgebung interessiert sind, können Sie versuchen, Chrome mit
--disable-web-security
Flag auszuführen .Ein weiterer Vorschlag: Haben Sie versucht, ein Bild programmgesteuert zu laden, um herauszufinden, ob dort weitere Informationen vorhanden sind?
quelle
Check out jQuery.ajaxError () Referenz: jQuery AJAX- Fehlerbehandlung (HTTP-Statuscodes) Es werden globale Ajax-Fehler abgefangen , die Sie über HTTP oder HTTPS auf verschiedene Arten behandeln können:
quelle
Leider gibt die heutige XHR-API des Browsers keinen expliziten Hinweis darauf, wann der Browser aufgrund einer "unsicheren Antwort" die Verbindung verweigert und auch wenn er dem HTTP / SSL-Zertifikat der Website nicht vertraut.
Es gibt jedoch Möglichkeiten, dieses Problem zu umgehen.
Eine Lösung, die ich gefunden habe, um festzustellen, wann der Browser dem HTTP / SSL-Zertifikat nicht vertraut, besteht darin, zuerst zu erkennen, ob ein XHR-Fehler aufgetreten ist (
error()
z. B. mithilfe des jQuery- Rückrufs), und dann zu überprüfen, ob der XHR-Aufruf ein https ist : // 'URL, und überprüfen Sie dann, ob die XHRreadyState
0 ist. Dies bedeutet, dass die XHR-Verbindung noch nicht einmal geöffnet wurde (was passiert, wenn der Browser das Zertifikat nicht mag).Hier ist der Code, in dem ich dies mache: https://github.com/maratbn/RainbowPayPress/blob/e9e9472a36ced747a0f9e5ca9fa7d96959aeaf8a/rainbowpaypress/js/le_requirejs/public/model_info__transaction_details.js
quelle
Ich glaube nicht, dass es derzeit eine Möglichkeit gibt, diese Fehlermeldungen zu erkennen, aber ein Hack, den Sie ausführen können, besteht darin, einen Server wie nginx vor Ihrem Anwendungsserver zu verwenden, sodass Sie bei einem Ausfall des Anwendungsservers einen Fehler erhalten Gateway-Fehler von Nginx mit
502
Statuscode, den Sie in JS erkennen können. Andernfalls wird bei einem ungültigen Zertifikat immer noch der gleiche generische Fehler angezeigtstatusCode = 0
.quelle