Comment Détecter l'Origine de la Croix (SCRO) Erreur par rapport aux Autres Types d'Erreurs pour XMLHttpRequest() en Javascript
Je suis en train d'essayer de détecter quand une XMLHttpRequest() échoue en raison d'une Origine de la Croix d'Erreur, par opposition à une mauvaise demande. Par exemple:
ajaxObj=new XMLHttpRequest()
ajaxObj.open("GET", url, true);
ajaxObj.send(null);
Envisager de 4 cas pour l'url:
Case 1: l'url est une adresse valide où access-control-allow-origin est correctement mis en
- Exemple:
http://192.168.8.35
où j'ai un serveur avecAccess-Control-Allow-Origin: *
dans l'en-tête - C'est facile à détecter que ajaxObj.readyState==4 et ajaxObj.status==200
Case 2: l'url est une adresse non valide à un serveur existant
- Exemple:
http://xyz.google.com
où le serveur répond, mais ce n'est pas une requête valide de la - Cette résultats dans ajaxObj.readyState==4 et ajaxObj.status==0
Case 3: l'url est un non-existant adresse ip du serveur
- Exemple:
http://192.168.8.6
sur mon réseau local où il n'y a rien à répondre - Cette résultats dans ajaxObj.readyState==4 et ajaxObj.status==0
Case 4: l'url est une adresse valide où access-control-allow-origin est PAS set
- Exemple:
http://192.168.8.247
où j'ai un serveur sansAccess-Control-Allow-Origin: *
dans l'en-tête - Cette résultats dans ajaxObj.readyState==4 et ajaxObj.status==0
Le problème est: Comment puis-je différencier le Cas 4 (access-control-allow-origin erreur) et les Cas 2&3?
Dans le Cas 4, le Chrome console de débogage affiche l'erreur:
XMLHttpRequest cannot load http://192.168.8.247/. Origin http://localhost is not allowed by Access-Control-Allow-Origin.
Comment puis-je faire cette erreur connue en Javascript?
J'ai essayé de trouver une indication dans ajaxObj
mais rien n'y semble être différent par rapport au Cas 2&3.
Ici est un simple test, j'ai utilisé:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>CORS Test</title>
<script type="text/javascript">
function PgBoot()
{
// doCORS("http://192.168.8.35"); //Case 1
// doCORS("http://xyz.google.com"); //Case 2
doCORS("http://192.168.8.6"); //Case 3
// doCORS("http://192.168.8.247"); //Case 4
}
function doCORS(url)
{
document.getElementById("statusDiv").innerHTML+="Processing url="+url+"<br>";
var ajaxObj=new XMLHttpRequest();
ajaxObj.overrideMimeType('text/xml');
ajaxObj.onreadystatechange = function()
{
var stat=document.getElementById("statusDiv");
stat.innerHTML+="readyState="+ajaxObj.readyState;
if(ajaxObj.readyState==4)
stat.innerHTML+=", status="+ajaxObj.status;
stat.innerHTML+="<br>";
}
ajaxObj.open("GET", url, true);
ajaxObj.send(null);
}
</script>
</head>
<body onload="PgBoot()">
<div id="statusDiv"></div>
</body>
</html>
Résultats à l'aide de google Chrome:
Processing url=http://192.168.8.35
readyState=1
readyState=2
readyState=3
readyState=4, status=200
Processing url=http://xyz.google.com
readyState=1
readyState=4, status=0
Processing url=http://192.168.8.6
readyState=1
readyState=4, status=0
Processing url=http://192.168.8.247
readyState=1
readyState=4, status=0
- Cela a été effectivement demandé sur stackoverflow.com/q/4844643/632951 (mais sans réponse).
Vous devez vous connecter pour publier un commentaire.
Non, il n'y a aucun moyen de faire la différence, selon le W3C Spec.
Voici comment la SCRO spécification précise le simple croix-origine de la demande procédure:
Dans le cas d'un échec de connexion réseau ou l'échec de la SCRO échange, la erreur de réseau étapes sont appliquées, il n'y a littéralement aucun moyen de distinguer entre les deux cas.
Pourquoi? L'un des avantages est qu'il empêche un attaquant de l'inspection de la topologie de réseau d'un réseau local. Par exemple, une page Web malveillante script pourrait trouver l'adresse IP de votre routeur en demandant à son interface HTTP, et donc d'apprendre quelques petites choses sur la topologie de votre réseau (par exemple, quelle est la taille de votre IP privée bloc est,
/8
ou/16
). Depuis votre routeur ne prend pas (ou ne devrait pas) envoyer les en-têtes de la SCRO, le script apprend absolument rien.Peut-être dans le cas où il aide tout le monde... une autre façon de gérer la différence entre les catégories de documents et d'erreur de réseau... peut fonctionner avec chrome ou firefox... (pas de solution parfaite si)
https://www.google.com
(existantes de la SCRO cible) par rapport àhttps://www.google.invalid
(inexistant) et ne pouvait pas voir une différence dans le script-visible comportement. Ce cas, est-ce censé couvrir? (Ou a le comportement a changé depuis Novembre 2016? La spec ne changent parfois, notamment sur les questions de la SCRO security.)De différencier une violation de la SCRO à partir d'autres ont échoué requêtes AJAX, vous pouvez examiner les en-têtes de réponse d'un CHEF de demande d'aide code côté serveur et de transmettre les résultats dans votre page. Par exemple, si la requête AJAX ne marche pas (état 0), on pourrait appeler ce script (appelons
cors.php
) et je sais que pour certains, si les en-têtes de réponse contenirAccess-Control-*
en-têtes.Exemples:
retourne
cors.php - Personnaliser au besoin
Côté Client harnais de test:
Harnais pilote:
Les résultats:
Étonnamment, vous pouvez le faire pour les images (et peut-être il ya une solution similaire pour les autres types de contenu). Le truc, c'est que n'est apparemment pas à l'égard de la SCRO, donc déclaration "url ne parvient pas à charger par XHR && url réussit à charge par img src" implique que l'URL fonctionne mais est SCRO bloqué.
Absolument, cela n'aide pas dans tous les cas, mais dans certains cas (par exemple, l'utilitaire de détecter si vous êtes suffisamment en passant de la SCRO), il peut faire l'affaire. Par exemple, j'ai voulu tirer un avertissement dans la console si mon appli (séparée frontend et backend) est installé correctement configuré URL de backend, et à tort, configuré de la SCRO sur le serveur, donc c'est parfaitement suffisant pour moi, car je peux servir d'une image pour faire des tests.
Voici ce que j'ai fait - même si elle n'a besoin de vous pour apporter des modifications au serveur distant (ajouter une nouvelle page).
Cependant, méfiez-vous qu'il est très difficile d'assurer la sécurité si la transmission des paramètres de toute façon (n'importe qui peut intégrer votre iframe, d'autres parties peuvent causer postMessage à la page ou l'iframe).
Et il n'est pas parfait (il ne détecte les erreurs qui ne sont pas transitoires one-offs).
Cependant bien que c'est beaucoup de travail, vous pouvez obtenir plus d'informations sur la cause de l'erreur. Très utile lorsque vous ne pouvez pas accéder directement au navigateur de vos utilisateurs.
PS: c'est complètement différent de la PHP réponse que suggère votre serveur doit s'entretenir avec le serveur distant (un) qui n'est pas beaucoup utiliser pour diagnostiquer les causes d'un échec de la communication, et (b) à l'aide de curl de PHP est en train de demander à votre serveur à être sérieusement pwned!