web-dev-qa-db-fra.com

Contourner Chrome Access-control-allow-Origin sur le système de fichiers local?

J'ai lu les autres mêmes sujets de politique d'origine ici sur SO, mais je n'ai vu aucune solution liée au système de fichiers local.

J'ai une application Web (au sens large du terme) qui doit être servie localement. J'essaie de charger une grande quantité de données après que l'utilisateur a chargé la page, selon ce qu'il fait sur la page Web. Dans Firefox 3.5 et IE8, je peux utiliser les méthodes AJAX () et GetScript () de jQuery pour ce faire, mais dans Chrome cela échoue en raison de la même politique d'origine).

XMLHttpRequest ne peut pas charger file://test/testdir/test.js. L'origine null n'est pas autorisée by Access-Control-Allow-Origin.

Cela se produit lorsque je fais quelque chose de simple comme

$.getScript("test.js");

Cela fonctionne parfaitement bien dans IE & Firefox.

Après avoir lu un tas de choses à ce sujet, j'ai décidé d'essayer d'écrire directement dans la tête du document. Dans la console en Chrome j'ai tapé ce qui suit:

var head = document.getElementsByTagName("head")[0];  
var script =document.createElement('script');   
script.id = 'uploadScript';  
script.type = 'text/javascript';  
script.src = "upload.js";   
head.appendChild(script);

Cela fonctionne très bien une fois collé dans la console - l'élément <script...test.js</script> Est ajouté à la tête, évalué et contenu chargé dans le DOM.

Je pensais que c'était réussi, jusqu'à ce que je mette ce code dans un appel de fonction. Le même code exact, lorsqu'il est appelé à partir d'une fonction, ajoute l'élément au mais n'évalue pas le fichier JavaScript. Je ne peux pas comprendre pourquoi. Si j'utilise la console de Chrome pour arrêter l'exécution dans la méthode qui ajoute l'élément à la et exécuter le code ci-dessus, il ne l'évalue pas. Cependant, si je suspends l'exécution et exécute exactement le même code (en le collant dans la fenêtre de la console), cela fonctionne. Je suis incapable d'expliquer cela. Est-ce que quelqu'un à déjà eu affaire avec ça avant?

J'ai lu les articles suivants SO, mais ils ne décrivent pas le problème que j'ai:

Façons de contourner la même politique d'origine
XMLHttpRequest Origin null n'est pas autorisé Access-Control-Allow-Origin pour le fichier: /// vers le fichier: /// (sans serveur)
CrossHite XMLHttpRequest

Encore une fois, mon dernier recours est de charger toutes les données au chargement de la page Web - Cela peut entraîner jusqu'à 10 secondes de retard dans le chargement de la page Web, ce qui n'est pas nécessaire pour 90% des utilisateurs de l'application.

Merci pour toutes suggestions/alternatives !!!

28
user210099

Je pense Je l'ai compris.

Tout ce que j'avais vraiment besoin de faire était d'ajouter un rappel dans ma balise <script>. Code final:

J'ai un élément nommé suivant ... Donc, dans la fonction $("#next").click() j'ai le code suivant. Cela n'est exécuté que s'ils cliquent sur "suivant".

//remove old dynamically written script tag-    
       var old = document.getElementById('uploadScript');  
   if (old != null) {  
     old.parentNode.removeChild(old);  
     delete old;  
   } 

   var head = document.getElementsByTagName("head")[0];  
   script = document.createElement('script');  
   script.id = 'uploadScript';  
   script.type = 'text/javascript';  
   script.src = 'test/' + scope_dir + '/js/list.js';  
   script.onload = refresh_page;    
   head.appendChild(script);  


function refresh_page(){  
   //perform action with data loaded from the .js file.  
}  

Cela semble fonctionner et permet à Chrome de charger dynamiquement des fichiers .js sur le système de fichiers local tout en contournant la stratégie de contrôle d'accès-autorisation-origine que j'ai rencontrée en essayant d'utiliser les fonctions jQuery.

4
user210099

Ok, fait beaucoup de tripotage et perdu beaucoup de temps. Mais je l'ai compris. La solution dans ma dernière réponse fonctionne bien pour Chrome et pour Mozilla. Mais cela ne fonctionne pas pour IE béni, car IE ne déclenchera pas l'événement onload: il pense qu'il a traité toutes les onloads dans ce fichier et vous ne pouvez pas le faire en faire un autre . Cependant, IE est très heureux de charger le fichier en utilisant la fonction JQuery getScript (ce qui Chrome ne permettra pas à cause de ccess-control-allow- Politique d'origine) - vous aurez besoin des bibliothèques JQuery pour que cela fonctionne. Voici donc ce que j'ai fini avec:

function getMyText(){
    var url='mylocalfile.js';
    if (jQuery.support.scriptEval) { 
        var old = document.getElementById('uploadScript');  
        if (old != null) {  
             old.parentNode.removeChild(old);  
             delete old;  
            } 
        var head = document.getElementsByTagName("head")[0]; 
        var script = document.createElement('script');
        script.id = 'uploadScript';
        script.type = 'text/javascript';
        script.onload = refresh_page; 
        script.src = url; 
        head.appendChild(script);  
    } else {
       $.getScript(url,function(){
            refresh_page();
      });
     }
}

function refresh_page() {
    alert(mytext);
}

Dans tout cela, mylocaltext.js définit tout mon html comme le contenu d'une variable, mytext. Moche, mais ça marche. jQuery.support.scriptEval est vrai pour les navigateurs intelligents qui déclenchent des événements de surcharge si le DOM change. IE ne fonctionne pas, ce qui l'envoie à .getScript; Chrome et d'autres le font, ce qui les envoie dans l'autre sens. Quoi qu'il en soit, cela fonctionne sur les fichiers locaux.

2
peter

Intéressant, mais comment utiliser la même technique pour charger un fichier HTML entier? Problème similaire au vôtre - J'ai des centaines de fichiers HTML que je souhaite inclure dans une page Web, selon ce que l'utilisateur souhaite voir. Il semble que je puisse utiliser cette technique pour charger dans une page HTML entière, quelque chose comme:

script.id = 'uploadScript';
script.type = 'text/html';
script.src = url; 
script.onload = refresh_page; 
head.appendChild(script);  

c'est-à-dire, dites-le charger en HTML. Je peux voir à partir de la console qu'il la charge dans la page, et je reçois un message 'Ressource interprétée comme script mais transférée avec le type MIME text/html'. Mais je ne peux pas trouver de moyen d'obtenir le code HTML chargé et conservé dans le script

1
peter