J'ai fait beaucoup de recherches et je n'ai pas trouvé de moyen de gérer cela. J'essaye d'effectuer un appel jQuery ajax d'un serveur https à un serveur https locahost exécutant une jetée avec un certificat auto-signé personnalisé. Mon problème est que je ne peux pas déterminer si la réponse est une connexion refusée ou une réponse non sécurisée (en raison du manque d'acceptation du certificat). Existe-t-il un moyen de déterminer la différence entre les deux scénarios? Les responseText
, et statusCode
sont toujours les mêmes dans les deux cas, même si dans la console Chrome, je peux voir une différence:
net::ERR_INSECURE_RESPONSE
net::ERR_CONNECTION_REFUSED
responseText
est toujours "" et statusCode
est toujours "0" dans les deux cas.
Ma question est la suivante: comment puis-je déterminer si un appel jQuery ajax a échoué en raison 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 arrêté ou s'il est opérationnel mais le certificat n'a pas encore été accepté.
$.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 en effectuant manuellement la demande, j'obtiens 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();
la source
function (xhr, status, msg) {...
Je doute qu'ils le feront, mais cela vaut la peine d'essayer.Réponses:
Il n'y a aucun moyen de le différencier des navigateurs Web les plus récents.
Spécification W3C:
Comme vous pouvez le lire, les erreurs réseau n'incluent pas la réponse HTTP qui inclut les erreurs, c'est pourquoi vous obtiendrez toujours 0 comme code d'état et "" comme erreur.
La source
Remarque : les exemples suivants ont été réalisés à l'aide de la version 43.0.2357.130 de Google Chrome et dans un environnement que j'ai créé pour émuler l'OP one. Le code de la configuration est au bas de la réponse.
Je pensais qu'une approche pour contourner ce problème serait de faire une requête secondaire sur HTTP au lieu de HTTPS comme réponse, mais je me suis souvenu que ce n'est pas possible car les nouvelles versions des navigateurs bloquent le contenu mixte.
Cela signifie que le navigateur Web n'autorisera pas une requête via HTTP si vous utilisez HTTPS et vice versa.
C'est comme ça depuis quelques années, mais les anciennes versions du navigateur Web comme Mozilla Firefox en dessous des versions 23 le permettent.
Preuve à ce sujet:
Faire une requête HTTP depuis HTTPS en utilisant la console Web Broser
entraînera l'erreur suivante:
La même erreur apparaîtra dans la console du navigateur si vous essayez de le faire d'une autre manière que l'ajout d'un Iframe.
L'utilisation de la connexion Socket a également été publiée en tant que réponse , j'étais à peu près sûr que le résultat sera le même / similaire, mais j'ai essayé.
Si vous essayez d'ouvrir une connexion de socket à partir de Web Broswer à l'aide de HTTPS vers un point de terminaison de socket non sécurisé, des erreurs de contenu mixte se termineront.
Ensuite, j'ai essayé de me connecter à un point de terminaison wss aussi voir si je pouvais lire des informations sur les erreurs de connexion réseau:
L'exécution de l'extrait de code ci-dessus avec le serveur désactivé entraîne:
Exécution de l'extrait de code ci-dessus avec le serveur activé
Mais encore une fois, l'erreur que la "fonction onerror" sortie vers la console n'a pas d'astuce pour différencier une erreur de l'autre.
L'utilisation d'un proxy comme le suggère cette réponse pourrait fonctionner mais seulement si le serveur "cible" a un accès public.
Ce n'était pas le cas ici, donc essayer d'implémenter un proxy dans ce scénario nous conduira au même problème.
Code pour créer le serveur HTTPS Node.js :
J'ai créé deux serveurs HTTPS Nodejs, qui utilisent des certificats auto-signés:
targetServer.js:
applicationServer.js:
Pour que cela fonctionne, vous devez installer Nodejs, vous devez générer des certificats séparés pour chaque serveur et les stocker dans les dossiers certs et certs2 en conséquence.
Pour l'exécuter
node applicationServer.js
, exécutez simplement etnode targetServer.js
dans un terminal (exemple ubuntu).la source
À partir de maintenant: il n'y a aucun moyen de différencier cet événement entre les navigateurs. Comme les navigateurs ne fournissent pas d'événement auquel les développeurs peuvent accéder. (Juillet 2015)
Cette réponse cherche simplement à fournir des idées pour une solution potentielle, albiet hacky et incomplète.
Avertissement: cette réponse est incomplète car elle ne résout pas complètement les problèmes d'OP (en raison de politiques d'origine croisée). Cependant, l'idée elle-même a un certain mérite qui est encore développé par: @artur grzesiak ici , en utilisant un proxy et ajax.
Après pas mal de recherches moi-même, il ne semble y avoir aucune forme de vérification d'erreur pour la différence entre une connexion refusée et une réponse non sécurisée, du moins en ce qui concerne le javascript fournissant une réponse pour la différence entre les deux.
Le consensus général de mes recherches est que les certificats SSL sont gérés par le navigateur, donc jusqu'à ce qu'un certificat auto-signé soit accepté par l'utilisateur, le navigateur verrouille toutes les demandes, y compris celles d'un code d'état. Le navigateur pourrait (s'il est codé) renvoyer son propre code de statut pour une réponse non sécurisée, mais cela n'aide vraiment rien, et même dans ce cas, vous auriez des problèmes de compatibilité avec le navigateur (chrome / firefox / IE ayant des normes différentes. .. encore une fois)
Étant donné que votre question initiale était de vérifier l'état de votre serveur entre la mise en service et le fait d'avoir un certificat non accepté, ne pourriez-vous pas faire une requête HTTP standard comme ça?
Certes, cela nécessite une demande supplémentaire pour vérifier la connectivité du serveur, mais le travail doit être effectué par un processus d'élimination. Je me sens toujours piraté et je ne suis pas un grand fan de la demande doublée.
la source
La réponse de @ Schultzie est assez proche, mais clairement
http
- en général - ne fonctionnera pashttps
dans l'environnement du navigateur.Ce que vous pouvez faire est d'utiliser un serveur intermédiaire (proxy) pour faire la demande en votre nom. Le proxy doit permettre soit de transférer la
http
demande depuis l'https
origine, soit de charger le contenu depuis les origines auto-signées .Avoir votre propre serveur avec un certificat approprié est probablement excessif dans votre cas - car vous pouvez utiliser ce paramètre au lieu de la machine avec un certificat auto-signé - mais il existe de nombreux services proxy ouverts anonymes .
Donc, deux approches qui me viennent à l'esprit sont:
.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 fonctionnait une fraction de seconde auparavant).Si vous n'êtes intéressé que par votre environnement local, vous pouvez essayer d'exécuter chrome avec
--disable-web-security
indicateur.Autre suggestion: avez-vous essayé de charger une image par programme pour savoir si plus d'informations y sont présentes?
la source
Consultez jQuery.ajaxError () Référence tirée de: jQuery AJAX Error Handling (HTTP Status Codes) Il détecte les erreurs Ajax globales que vous pouvez gérer de plusieurs manières via HTTP ou HTTPS:
la source
Malheureusement, l'API XHR du navigateur actuel ne fournit pas d'indication explicite lorsque le navigateur refuse de se connecter en raison d'une "réponse non sécurisée", et également lorsqu'il ne fait pas confiance au certificat HTTP / SSL du site Web.
Mais il existe des moyens de contourner ce problème.
Une solution que j'ai trouvée pour déterminer quand le navigateur ne fait pas confiance au certificat HTTP / SSL, consiste d'abord à détecter si une erreur XHR s'est produite (en utilisant le
error()
rappel jQuery par exemple), puis à vérifier si l'appel XHR est à un 'https : // 'URL, puis vérifiez si le XHRreadyState
est 0, ce qui signifie que la connexion XHR n'a même pas été ouverte (ce qui se produit lorsque le navigateur n'aime pas le certificat).Voici le code où je fais cela: https://github.com/maratbn/RainbowPayPress/blob/e9e9472a36ced747a0f9e5ca9fa7d96959aeaf8a/rainbowpaypress/js/le_requirejs/public/model_info__transaction_details.js
la source
Je ne pense pas qu'il existe actuellement un moyen de détecter ces messages d'erreur, mais un hack que vous pouvez faire est d'utiliser un serveur comme nginx devant votre serveur d'applications, de sorte que si le serveur d'applications est en panne, vous obtiendrez un mauvais erreur de passerelle de nginx avec le
502
code d'état que vous pouvez détecter dans JS. Sinon, si le certificat n'est pas valide, vous obtiendrez toujours la même erreur générique avecstatusCode = 0
.la source