Déterminer si l'appel ajax a échoué en raison de l'insécurité de la réponse ou de connexion refusée
J'ai fait beaucoup de recherche, et ne pouvait pas trouver un moyen de gérer cela. Je suis en train d'effectuer un appel ajax jQuery à partir d'un serveur https à un locahost https serveur exécutant jetée avec un certificat auto-signé. Mon problème est que je ne peut pas déterminer si la réponse de connexion est refusée ou qu'une insécurité réponse (en raison de l'absence de certificat d'acceptation). Est-il un moyen de déterminer la différence entre les deux scénarios? Le responseText
, et statusCode
sont toujours les mêmes dans les deux cas, même si dans la console chromée je vois une différence:
net::ERR_INSECURE_RESPONSE
net::ERR_CONNECTION_REFUSED
responseText
est toujours "" et statusCode
est toujours à "0" pour les deux cas.
Ma question est, comment puis-je déterminer si un jQuery ajax appel a échoué en raison de ERR_INSECURE_RESPONSE
ou en raison de ERR_CONNECTION_REFUSED
?
Une fois que le certificat est accepté tout fonctionne bien, mais je veux savoir si le serveur localhost est à l'arrêt, ou à sa place et l'exécution, mais le certificat n'a pas encore été acceptée.
$.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.
}
});
Même d'effectuer manuellement la demande-je obtenir le même résultat:
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();
- je vais poster mon code, mais ce n'est pas un code javascript d'erreur. Veuillez lire attentivement ma question.
- Les deux autres erreurs de rappel des arguments de donner toute information additionnelle?
function (xhr, status, msg) {...
Je doute qu'ils seront, mais la peine d'essayer. - Obtenez-vous les différents codes d'erreur dans un autre navigateur? Cela peut être généré et bloqué par google Chrome.
- tous les paramètres de l'erreur de rappel sont toujours les mêmes
- tous les navigateurs sont de me donner les mêmes réponses. Je suis perplexe à ce sujet.
- Pas de. À partir d'un serveur vers un autre serveur. Le serveur jetty (fonctionnement en locahost) a correctement défini la SCRO en-têtes de parce que une fois que j'ai accepter le certificat, tout fonctionne comme prévu. Je veux déterminer si le certificat doit être accepté ou la jetée de l'est vers le bas.
- Il est tout à fait possible que le manque d'informations à partir du navigateur est entièrement volontaire. Simplement une "erreur" serait de fournir certains nombre d'informations pour un projet de hacker, par exemple. "Ce système a quelque chose à l'écoute sur le port etc."
- Êtes-vous en mesure d'accéder à la ressource à l'url dans le navigateur? Normalement, un code d'état de 0 se produit avec le cross-site scripting (où l'accès est refusé) ou de demander une URL qui est inaccessible (erreur de frappe, des problèmes de DNS, etc). Peut-être avoir un coup d'oeil à this
- Oui, j'ai accès à la ressource par l'url, il frappe à partir de mon navigateur fonctionne bien et j'ai l'écran où vous devez accepter le certificat.
- Avez-vous regardé tout le serveur en-têtes de réponse via la fonction
XMLHttpRequest.getAllResponseHeaders()
il pourrait y avoir quelque chose dans les en-têtes qui peuvent les aider. - Je l'ai essayé. Même résultat malheureusement.
- Pourquoi essayez-vous de le faire dans le navigateur? Pourquoi ne pas le faire côté serveur où vous avez accès à plus d'informations détaillées sur l'erreur?
- ce n'est pas quelque chose que je veux, c'est quelque chose que j'ai besoin de la conception et de la nature de ce que je suis en développement. côté serveur n'est pas une option.
Vous devez vous connecter pour publier un commentaire.
Il n'y a aucun moyen de le différencier de la plus récente des Navigateurs Web.
Spécification du W3C:
Comme vous pouvez le lire, les erreurs du réseau n'inclut pas de réponse HTTP qui comprennent les erreurs, c'est pourquoi vous obtenez toujours 0 comme code d'état, et de "" comme une erreur.
Source
Note: Les exemples suivants ont été réalisés à l'aide de Google Chrome Version 43.0.2357.130 et dans un environnement que j'ai créé pour émuler OP un. Code pour le jeu il est en bas de la réponse.
J'ai bien qu'une approche Pour contourner ce serait faire un secondaire demande via HTTP au lieu de HTTPS comme Cette réponse mais j'ai souvenir que n'est pas possible vu que les nouvelles versions de navigateurs bloc de contenu mixte.
Qui signifie que le Navigateur Web ne permettra pas à la demande par HTTP si vous utilisez le protocole HTTPS et vice versa.
Cela a été comme ça depuis quelques années, mais les plus âgés Web versions de Navigateur comme Mozilla Firefox en dessous des versions 23 le permettent.
Des éléments de preuve à ce sujet:
De faire une requête HTTP, HTTPS avec du navigateur Web de la console
entraînera l'erreur suivante:
Même message d'erreur apparaît dans le navigateur de la console si vous essayez de faire cela dans d'autres façons, comme l'ajout d'un Iframe.
À l'aide de la connexion Socket a également été Posté comme une réponse, je suis presque sûr que le résultat sera le même mais j'ai essayer.
En essayant d'Ouvrir un socket de connexion à partir du Navigateur Web en utilisant le protocole HTTPS pour un non Secure socket point de terminaison de la fin à contenu mixte erreurs.
Puis j'ai essayé de vous connecter à un wss point de terminaison de trop voir Si j'ai pu lire quelques informations sur les erreurs de connexion réseau:
De l'exécution de l'extrait de code ci-dessus avec le Serveur éteint résultats dans:
De l'exécution de l'extrait de code ci-dessus avec le Serveur allumé
Mais encore une fois, l'erreur que le "onerror de la fonction" sortie de la console n'ont pas une astuce pour différencier une erreur de l'autre.
L'utilisation d'un proxy comme cette réponse suggèrent pourraient travailler, mais seulement si la "cible", le serveur a accès public.
Ce n'était pas le cas ici, donc essaie de mettre en place un proxy dans ce scénario va Nous conduire à le même problème.
Code pour créer Node.js serveur HTTPS:
J'ai créé deux Nodejs serveurs HTTPS, qui utilisent les certificats auto-signés:
targetServer.js:
applicationServer.js:
Pour le faire fonctionner, vous devez avoir Nodejs Installé, Besoin de générer des certificats séparés pour chaque serveur et de le stocker dans les dossiers certs et certs2 en conséquence.
Seulement exécuter
node applicationServer.js
etnode targetServer.js
dans un terminal (ubuntu par exemple).Dès maintenant: Il n'y a aucun moyen de distinguer cet événement entre browers. Comme les navigateurs ne fournissent pas un événement pour les développeurs d'accès. (Juillet 2015)
Cette réponse vise uniquement à fournir des idées pour un potentiel, albiet hacky et incomplète, la solution.
Avertissement: cette réponse est incomplète car elle ne permet pas complètement résoudre OP questions (en raison de cross-origin politiques). Cependant l'idée elle-même n'a quelque mérite qui est expliquée par: @artur grzesiak ici, l'utilisation d'un proxy et ajax.
Après un peu de recherches moi-même, il ne semble pas être de toute forme de vérification des erreurs pour la différence entre la connexion refusée et une insécurité de réponse, au moins autant que javascript fournir une réponse pour la différence entre les deux.
Le consensus général de mes recherches que les certificats SSL sont gérées par le navigateur, donc, jusqu'à ce qu'un certificat auto-signé est accepté par l'utilisateur, le navigateur se bloque toutes les demandes, y compris celles pour un code d'état. Le navigateur pourrait (si le code d') renvoyer son propre code d'état de l'insécurité de réponse, mais qui n'aident pas vraiment à quoi que ce soit, et même alors, vous finiriez par avoir des problèmes avec la compatibilité du navigateur (chrome/firefox/IE d'avoir des normes différentes... une fois de plus)
Depuis votre question initiale était de vérifier l'état de votre serveur entre l'être jusqu'au lieu d'avoir un certificat de non acceptée, vous ne pourriez pas vous en faire un standard de requête HTTP comme?
Accordé ce n'nécessitent une requête supplémentaire pour vérifier la connectivité du serveur, mais il doit obtenir le travail fait par le processus d'élimination. Se sent toujours hacky bien, et je ne suis pas un grand fan de la double demande.
@Schultzie la réponse est assez proche, mais clairement
http
- en général - ne fonctionnera pas dehttps
dans le navigateur de l'environnement.Ce que vous pouvez faire est d'utiliser un serveur intermédiaire (proxy) pour en faire la demande en votre nom. Le proxy doit permettre soit à l'avant
http
demande dehttps
origine ou pour charger le contenu d' auto-signé origines.Avoir votre propre serveur avec le bon certificat est probablement inutile dans votre cas, comme vous pouvez utiliser ce paramètre à la place de la machine avec un certificat auto-signé-mais il y a plein de anonyme proxy ouvert services là.
Donc deux approches qui viennent à mon esprit:
.parentWindow
. Si votre fenêtre a reçu un message, vous pouvez être sûr que le serveur est en cours d'exécution (ou, plus précisément, a été l'exécution d'une fraction de seconde avant).Si vous êtes uniquement intéressé par votre environnement local, vous pouvez essayer d'exécuter chrome avec
--disable-web-security
drapeau.Une autre suggestion: avez-vous essayez de charger une image par programmation de savoir si plus d'info il y a?
Découvrez jQuery.ajaxError()
Prise de référence à partir de : jQuery AJAX gestion des Erreurs (Codes d'État HTTP)
Il attrape mondiale Ajax, les erreurs que vous pouvez gérer dans un certain nombre de façons via HTTP ou HTTPS:
Malheureusement, l'actuelle navigateur XHR API ne donne pas une indication explicite lorsque le navigateur refuse de se connecter en raison d'une "insécurité de réponse", et aussi quand il n'a pas confiance dans le site web HTTP/SSL certificat.
Mais il ya des façons de contourner ce problème.
Une solution je suis venu avec des pour déterminer si le navigateur ne fait pas confiance à l'adresse HTTP/SSL certificat, est d'abord de détecter si une XHR erreur s'est produite (à l'aide de jQuery
error()
de rappel par exemple), puis vérifier si le XHR est un appel à une "https://" de l'URL, puis vérifiez si le XHRreadyState
est de 0, ce qui signifie que le XHR connexion n'a même pas été ouvert (qui est ce qui se passe lorsque le navigateur n'aime pas le certificat).Voici le code où je fais ceci:
https://github.com/maratbn/RainbowPayPress/blob/e9e9472a36ced747a0f9e5ca9fa7d96959aeaf8a/rainbowpaypress/js/le_requirejs/public/model_info__transaction_details.js#L88
Je ne pense pas qu'il y a actuellement un moyen de détecter ces messages d'erreur, mais un hack que vous pouvez faire est d'utiliser un serveur comme nginx en face de votre serveur d'application, de sorte que si l'application serveur est en panne, vous aurez un bad gateway erreur de nginx avec
502
code d'état qui vous permet de détecter en JS. Sinon, si le certificat n'est pas valide, vous aurez toujours la même erreur générique avecstatusCode = 0
.