2013-01-04 2 views
9

ich ein iframe programmatisch die „Daten“ URI bin erstellen:Zugriff Programmatically einen Iframe, der eine Daten URI als Quelle verwendet

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

Dieser Rahmen Lasten in Ordnung, aber es scheint, dass programmatisch mit dem iframe Arbeits führt zu domänenübergreifenden Sicherheitsprüfungen.

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

Wirft einen Fehler in Chrome und 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.

Hier ist eine Geige, die Sicherheit Fehler zeigt: http://jsfiddle.net/bhGcw/4/

Firefox und Opera nicht diese Ausnahme auslösen und die iframe Inhalte erlauben zu sein geändert. Scheint so, als ob Webkit ein leeres Protokoll für Daten-URIs sieht und sieht dies als eine domänenübergreifende Verletzung an.

Gibt es einen Weg um dies zu umgehen?

+1

ist das das? http://code.google.com/p/chromium/issues/detail?id=82402 Es ist für Chrom, nicht Chrom, aber vielleicht hat es das gleiche Problem. Ich habe auch ein Sicherheitsproblem für Phishing gefunden, welches Chrome versucht zu verhindern, es könnte es auch sein – llamerr

+0

Ja, das sieht definitiv ähnlich aus. Hatte gehofft, dass es einen Workaround gab, aber scheint, dass es nicht gibt. –

Antwort

5

Es scheint, dass Webkit hat einen einfachen String-Vergleich in ihren 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"; 

    ... 
} 

Es sieht aus wie Chrom wird strenger als die HTML5-Spezifikation, zumindest nach den folgenden Fehlermeldungen:

Chrom-Entwickler scheinen nicht dafür zu sein, diese Regel zu lockern. Bummel.

+1

Interessanter Kommentar, aber leider beantwortet es nicht die Frage – mems

7

Es ist ein bisschen spät, wie wäre es mit statt einer Daten-URL verwenden Sie das HTML5-Attribut 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> 

Es ist ein Beispiel an http://jsfiddle.net/ff3bF/

+2

srcdoc funktioniert nicht auf IE/Edge. – Seanonymous

+1

Das ist ein bisschen enttäuschend.Jemand hat einen Polyfill erstellt (https://github.com/jugglinmike/srcdoc-polyfill) – Jamie

3

Die Antwort von @jamie funktioniert gut in einen Iframe zum Laden von HTML vorbringen und damit nachfolgende programatic Interaktion mit dem Inhaltsdokument.

XHTML ist nicht so einfach.

Das Attribut srcdoc scheint auf HTML beschränkt zu sein, nicht auf XHTML.

Eine Umgehung ist die Verwendung einer Blob URL, die die content-type spezifiziert werden kann.

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

Diese Technik funktioniert für mindestens Chrome, Firefox und Safari.