web-dev-qa-db-fra.com

Utilisation d'iframe avec des fichiers locaux dans Chrome

J'ai du mal à trouver comment accéder à une page chargée dans un iframe à partir de la page externe. Les deux pages sont des fichiers locaux et j'utilise Chrome.

J'ai une page externe et de nombreuses pages internes. La page externe doit toujours afficher le titre de la page pour la page interne (cela a du sens dans mon application, peut-être moins dans cet exemple dépouillé). Cela fonctionne sans aucun problème dans AppJS, mais on m'a demandé de faire fonctionner cette application directement dans le navigateur. J'obtiens l'erreur " Bloqué un cadre avec Origin" null "d'accéder à un cadre avec Origin" null ". Les protocoles, domaines et ports doivent correspondre. ".

Je pense que cela est dû à la même politique d'origine de Chrome concernant les fichiers locaux, mais cela ne m'a pas aidé à résoudre le problème directement. Je peux contourner le problème dans cet exemple dépouillé en utilisant la méthode window.postMessage per façons de contourner la même politique d'origine . Cependant, au-delà de cet exemple, je veux également manipuler le DOM de la page intérieure à partir de la page extérieure, car cela rendra mon code beaucoup plus propre - donc la publication de messages ne fera pas tout à fait le travail.

Page extérieure

<!DOCTYPE html>
<html>
    <head> 
        <meta name="viewport">
    </head> 
    <body>
        This text is in the outer page
        <iframe src="html/Home.html" seamless id="PageContent_Iframe"></iframe>
        <script src="./js/LoadNewPage.js"></script>
    </body>
</html>

Page intérieure

<!DOCTYPE html>
<html>
    <head>
        <title id="Page_Title">Home</title> 
        <meta name="viewport">
    </head> 
    <body>
        This text is in the inner page
    </body>
</html>

Javascript

var iFrameWindow = document.getElementById("PageContent_Iframe").contentWindow;
var pageTitleElement = iFrameWindow.$("#Page_Title");

Per Est-il probable que les futures versions de Chrome prennent en charge contentWindow/contentDocument lorsque iFrame charge un fichier html local à partir d'un fichier html local? , j'ai essayé de lancer Chrome avec le drapeau

--allow-file-access-from-files

Mais il n'y a pas eu de changement dans les résultats.

Par Désactiver la même politique d'origine dans Chrome , j'ai essayé de lancer Chrome avec le drapeau

--disable-web-security

Mais encore une fois, les résultats n'ont pas changé.

Par que fait document.domain = document.domain? , j'ai demandé aux deux pages d'exécuter la commande

document.domain = document.domain;

Cela a entraîné l'erreur " Bloqué un cadre avec l'origine" null "d'accéder à un cadre avec l'origine" null ". Le cadre demandant l'accès défini" document.domain "à" ", mais le cadre n'est pas accessible. Les deux doivent définir "document.domain" sur la même valeur pour autoriser l'accès. "

Pour le plaisir, j'ai fait exécuter la commande sur les deux pages

document.domain = "foo.com";

Cela a entraîné l'erreur " Erreur non interceptée: SecurityError: exception DOM 18 ".

Je patauge. Toute aide de personnes plus compétentes serait fantastique! Merci!

36

Par notre discussion dans mon cube il y a une minute :)

J'ai rencontré ce même problème ( la réponse de publication Ajax de js express continue de générer des erreurs ) en essayant d'obtenir une AJAX demande de publication pour fonctionner correctement.

Ce qui m'a amené à le faire, ce n'est pas d'exécuter le fichier directement à partir du système de fichiers, mais plutôt de l'exécuter à partir d'un serveur local. J'ai utilisé node pour exécuter express.js. Vous pouvez installer express avec la commande suivante: npm install -g express

Une fois cela accompli, vous pouvez créer un projet express avec la commande suivante: express -s -e expressTestApp

Maintenant, dans ce dossier, vous devriez voir un fichier nommé app.js et un dossier nommé public. Placez les fichiers html avec lesquels vous souhaitez travailler dans le dossier public. J'ai remplacé le fichier app.js par le code suivant:

var express = require('/usr/lib/node_modules/express');
var app = express();

app.use(function(err, req, res, next){
  console.error(err.stack);
  res.send(500, 'Something broke!');
});

app.use(express.bodyParser());
app.use(express.static('public'));

app.listen(5555, function() { console.log("Server is up and running");  });

Notez que la ligne requise peut être différente. Vous devez trouver où votre système a réellement mis express. Vous pouvez le faire avec la commande suivante: Sudo find/-name express

Maintenant, démarrez le serveur Web express avec la commande suivante: node app.js

À l'heure actuelle, le serveur Web est opérationnel. Allez-y et ouvrez un navigateur et accédez à votre adresse IP (ou si vous êtes sur la même machine que votre serveur, 127.0.0.1). Utilisez l'adresse IP: numéro_port\nom_fichier.html où le numéro de port est le 5555 dans le fichier app.js que nous avons créé.

Maintenant, dans ce navigateur, vous ne devriez plus (et ne l'aviez pas quand nous l'avons testé) avoir ces mêmes problèmes.

12
Brian

Je suis désolé de vous dire que j'ai essayé pendant des semaines de résoudre ce problème (j'en avais besoin pour un projet) et ma conclusion est que ce n'est pas possible.

Il y a beaucoup de problèmes autour de l'accès local via javascript avec chrome, et certains d'entre eux peuvent être résolus en utilisant --allow-file-access-from-files et --disable-web-security, y compris certaines fonctionnalités hors ligne HTML5, mais je pense vraiment qu'il n'y a aucun moyen d'accéder aux fichiers locaux.

Je vous recommande de ne pas perdre votre temps à essayer de contourner cela et d'essayer de publier des messages que vous pouvez interpréter dans les pages intérieures, afin que vous puissiez y apporter les modifications DOM.

18
panthalassa

file: // protocol et http: // protocol font que les choses se comportent très différemment en ce qui concerne les iframes. J'ai eu les mêmes problèmes que vous décrivez avec une application sur PhoneGap qui utilise le protocole de fichier pour accéder à tous les fichiers locaux dans le dossier assets/www local.

Il semble que les navigateurs modernes empêchent l'affichage des fichiers "locaux" en utilisant le protocole de fichier dans les iframes pour des raisons de sécurité.

Nous avons fini par vider les iframes et à n'utiliser que des divs comme "fenêtres". Heureusement, la taille globale de notre application n'était pas si grande que nous avons réussi à tout charger sur une seule page.

2
Peter Drinnan