2013-01-04 7 views
9

Sto creando un iframe di programmazione utilizzando i "dati" URI:di programmazione si accede a un iframe che utilizza un URI di dati come fonte

<iframe id="myFrame" src='data:text/html;charset=utf-8,<!DOCTYPE html><html><head></head><body><h1>Hello.</h1></body></html>'></iframe>​ 

Questo telaio carichi bene, ma sembra che lavorare con l'iframe di programmazione colpisce i controlli di sicurezza tra domini.

var iframeDoc = document.getElementById('myFrame').contentWindow.document; 
$(iframeDoc.body).find('h1').text('Changed'); 

genera un errore in Chrome e Safari:

Unsafe JavaScript attempt to access frame with URL data:text/html;charset=utf-8,... from frame with URL http://... The frame requesting access has a protocol of 'http', the frame being accessed has a protocol of ''. Protocols must match.

Ecco un violino che mostra l'errore di sicurezza: http://jsfiddle.net/bhGcw/4/

Firefox e Opera non gettare questa eccezione e consentire il contenuto iframe per essere cambiato. Sembra che Webkit veda un protocollo vuoto per gli URI di dati e lo vede come una violazione tra domini.

C'è qualche modo per aggirare questo?

+1

è questo? http://code.google.com/p/chromium/issues/detail?id=82402 è per Chromium, non per Chrome, ma forse ha lo stesso problema. inoltre ho trovato qualche problema di sicurezza per il phishing, che Chrome cerca di prevenire, potrebbe essere anche questo – llamerr

+0

Sì, sembra decisamente correlato. Speravo che ci fosse una soluzione alternativa, ma sembra che non ci sia. –

risposta

5

Sembra che Webkit fa un semplice confronto di stringhe nella loro domain checking code:

String DOMWindow::crossDomainAccessErrorMessage(DOMWindow* activeWindow) 
{ 
    ... 

    SecurityOrigin* activeOrigin = activeWindow->document()->securityOrigin(); 
    SecurityOrigin* targetOrigin = document()->securityOrigin(); 
    if (targetOrigin->protocol() != activeOrigin->protocol()) 
     return message + " The frame requesting access has a protocol of '" + activeOrigin->protocol() + "', the frame being accessed has a protocol of '" + targetOrigin->protocol() + "'. Protocols must match.\n"; 

    ... 
} 

Sembra cromo è essere più severa di quanto le specifiche HTML5, almeno secondo le seguenti segnalazioni di bug:

Gli sviluppatori di cromo non sembrano essere a favore di questa regola. Bummer.

+1

Commento interessante, ma sfortunatamente non risponde alla domanda – mems

7

È un po 'tardi, e invece di usare un URL di dati, si usa l'attributo HTML5 srcdoc.

<iframe id="iframe" srcdoc='<html><body><h1>Hello!</h1></body></html>'></iframe> 
<script type="text/javascript"> 
    $(function(){ 
     $($("iframe")[0].contentWindow.document).find("h1").text("Modified from the parent window!"); 
    }); 
</script> 

C'è un esempio a http://jsfiddle.net/ff3bF/

+2

srcdoc non funziona su IE/Edge. – Seanonymous

+1

Questo è un po 'deludente.Qualcuno ha creato un polyfill (https://github.com/jugglinmike/srcdoc-polyfill) – Jamie

3

La risposta proposta da @jamie funziona bene per il caricamento HTML in un iframe e permettendo la successiva interazione con il documento programmatico contenuti.

XHTML non è così semplice.

L'attributo srcdoc sembra essere limitato all'HTML, non all'XHTML.

Una soluzione è utilizzare un URL Blob che consente di specificare content-type.

var documentSource = '<?xml version="1.0" encoding="UTF-8"?>\n<html xmlns="http://www.w3.org/1999/xhtml">\n<head>...'; 
var blob = new Blob([documentSource], { type: "application/xhtml+xml" }); 
iframe.src = URL.createObjectURL(blob); 

Questa tecnica funziona per almeno Chrome, Firefox e Safari.

Problemi correlati