2013-07-30 10 views
35

Sto attraversando un periodo difficile per capire come accedere a una pagina caricata in un iframe dalla pagina esterna. Entrambe le pagine sono file locali e sto utilizzando Chrome.Utilizzo di iframe con file locali in Chrome

Ho una pagina esterna e molte pagine interne. La pagina esterna dovrebbe sempre mostrare il titolo della pagina per la pagina interna (ha senso nella mia applicazione, forse meno in questo esempio ridotto). Funziona senza problemi in AppJS, ma mi è stato richiesto di far funzionare questa app direttamente nel browser. Viene visualizzato l'errore "Bloccato un frame con origine" null "dall'accesso a un frame con origine" null ".I protocolli, domini e porte devono corrispondere.".

Penso che questo sia dovuto allo stesso criterio di origine di Chrome relativo ai file locali, ma questo non mi ha aiutato a risolvere il problema direttamente. Posso aggirare il problema in questo esempio ridotto utilizzando il metodo window.postMessage per Ways to circumvent the same-origin policy. Tuttavia, andando oltre questo esempio, voglio anche manipolare il DOM della pagina interna dalla pagina esterna, poiché questo renderà il mio codice molto più pulito, quindi i messaggi di pubblicazione non faranno il lavoro.

esterno Pagina

<!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> 

interno Pagina

<!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 Is it likely that future releases of Chrome support contentWindow/contentDocument when iFrame loads a local html file from local html file?, ho cercato di lanciare Chrome con la bandiera

--allow-file-access-from-files 

Ma non ci sono stati cambiamenti nei risultati.

Per Disable same origin policy in Chrome, ho cercato di lanciare Chrome con la bandiera

--disable-web-security 

Ma ancora una volta non c'era alcun cambiamento nei risultati.

Per What does document.domain = document.domain do?, ho avuto entrambe le pagine eseguire il comando

document.domain = document.domain; 

Ciò ha determinato l'errore "bloccato un telaio con origine 'nullo' l'accesso a un telaio con origine 'nullo'. Il telaio richiede l'accesso impostare "document.domain" su "", ma non è stato necessario accedere al frame. Entrambi devono impostare "document.domain" sullo stesso valore per consentire l'accesso. "

Per divertimento, avevo entrambe le pagine eseguire il comando

document.domain = "foo.com"; 

Ciò ha provocato l'errore "Errore non rilevato: SecurityError: DOM Exception 18".

Sono in difficoltà. Qualsiasi aiuto da parte di persone più esperte sarebbe fantastico! Grazie!

risposta

12

Per la nostra discussione nel mio cubo di appena un minuto fa :)

mi ha colpito questo stesso problema (Ajax post response from express js keeps throwing error) cercando di ottenere una richiesta POST AJAX per funzionare correttamente.

Quello che mi ha preso in giro non è eseguire il file direttamente dal file system ma eseguirlo da un server locale. Ho usato il nodo per eseguire express.js. È possibile installare espressa con il seguente comando: npm install -g express

Una volta che si compie, è possibile creare un progetto espressa con il seguente comando: esprimere -s -e expressTestApp

Ora, in quella cartella, si dovrebbe vedere un file denominato app.js e una cartella denominata public. Metti i file html con i quali desideri lavorare nella cartella pubblica. Ho sostituito il file app.js con il seguente codice:

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"); }); 

Nota, la riga richiesta potrebbe essere diversa. Devi trovare dove il tuo sistema è effettivamente espresso. Potete farlo con il seguente comando: sudo find/-name esprimono

Ora, avviare il server web espressa con il seguente comando: nodo app.js

In questo momento, il server web è installato e funzionante. Vai avanti e apri un browswer e vai al tuo indirizzo IP (o se sei sulla stessa macchina del tuo server, 127.0.0.1). Utilizza l'indirizzo IP: portnumber \ filename.html dove il numero di porta è il 5555 nel file app.js che abbiamo creato.

Ora, in quel browser, non dovresti (e non l'hai provato quando lo abbiamo testato) avere qualcuno di questi stessi problemi.

+7

Nota: se hai installato Python, puoi applicare lo stesso approccio che suggerisci qui e [configura un server Web una riga] (http://stackoverflow.com/a/532710/710446): 'python -m SimpleHTTPServer [ porta] ' – apsillers

+0

Wow, è davvero bello. Non l'avevo visto. L'ho provato sullo stesso codice sorgente e funziona, ma più lento di espresso. Essere operativi in ​​modo rapido è piuttosto sorprendente e sicuramente un compromesso da considerare. – Brian

+1

Con Python 3, utilizzare invece: 'python -m http.server [porta]' – taleinat

17

Mi dispiace dirvi che ho provato durante settimane a risolvere questo problema (ne avevo bisogno per un progetto) e la mia conclusione è che non è possibile.

Ci sono un sacco di problemi arround accesso locale attraverso javascript con bicromato di potassio, e alcuni di essi possono essere risolti utilizzando --allow-file-access-from-files e --disable-web-security, tra cui alcune funzioni offline HTML5, ma io sicuramente credo che ci sia alcun modo per accedere ai file locali.

Ti consiglio di non perdere tempo a cercare di circumnavigare questo e di provare a postare messaggi che puoi interpretare nelle pagine interne, così puoi fare le modifiche DOM lì.

+0

Ragazzo, è un peccato. Grazie mille per la tua risposta! – ATTD

2

file: // protocollo e protocollo http: // fanno sì che le cose si comportino in modo molto diverso rispetto agli iframe. Ho avuto gli stessi problemi che descrivi con un'app su PhoneGap che utilizza il protocollo file per accedere a tutti i file locali all'interno della cartella risorse locali/www.

Se sembra che i browser moderni impediscano la visualizzazione di file "locali" utilizzando il protocollo file in iframe per motivi di sicurezza.

Abbiamo finito per scaricare iframe e utilizzare solo div come "viewport". Fortunatamente la dimensione complessiva della nostra app non era così grande, quindi siamo riusciti a caricare tutto in un'unica pagina.

+0

Sono piuttosto curioso di sapere quali sono questi motivi di sicurezza. Ad essere onesti, non vedo alcuna ragione per cui questo dovrebbe essere vietato. Se esiste un caso specifico, sarebbe bello se Chrome potesse fornire un messaggio sensato, poiché mi aspetto che il protocollo, il dominio e la porta siano gli stessi per i file locali. –

+0

@JacekPrucia Prenderò una crepa: il motivo è che se qualcuno ti dà un'app che accede a file locali, quindi se Chrome non la blocca, può andare avanti e leggere/scrivere i tuoi file locali. (Questo non è ovvio se stai lavorando sulla tua app e vuoi semplicemente accedere al tuo filesystem, ma diventa più ovvio se distribuisci la tua app ad altri.) –

+0

@martinjakubik Certo che può, ma non vedo ancora un male in quello. Supponiamo che la tua pagina sia rootata in "C: \ Projects \ Test \ Test.html". Una pagina dannosa può solo scrivere file locali in quella particolare cartella (stessa politica di origine quando applicata alle cartelle). Certo che può creare file dannosi - app che si nascondono come innocenti screen saver, tuttavia è ancora necessario l'intervento dell'utente per il danno da fare. Se usi semplicemente l'app, continuo a non vedere in che modo può danneggiare il sistema locale. –

Problemi correlati