2013-01-04 11 views
9

Tworzę iframe programowo przy użyciu „dane” URI:Programowy dostęp do iframe, który używa danych URI jako źródło

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

Ta ramka ładunki w porządku, ale wydaje się, że działa z iframe programowo uderza w sprawdzenia bezpieczeństwa w wielu domenach.

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

Zgłasza błąd w Chrome i 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.

Oto skrzypce pokazując błąd zabezpieczeń: http://jsfiddle.net/bhGcw/4/

Firefox i Opera nie rzucać ten wyjątek i pozwolić zawartość iframe być zmienione. Wygląda na to, że Webkit widzi pusty protokół dla identyfikatorów URI danych i widzi to jako naruszenie między domenami.

Czy jest jakiś sposób obejścia tego?

+1

czy tak? http://code.google.com/p/chromium/issues/detail?id=82402 dotyczy chromu, a nie chrome, ale może ma ten sam problem. również znalazłem problem z bezpieczeństwem dla phishingu, którego chrome próbuje zapobiegać, może to być też zbyt. – llamerr

+0

Tak, to zdecydowanie wygląda na powiązane. Miał nadzieję, że istnieje obejście, ale wydaje się, że tak nie jest. –

Odpowiedz

5

Wydaje się, że Webkit robi proste porównanie ciąg w ich 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"; 

    ... 
} 

to wygląda Chromium są bardziej rygorystyczne niż specyfikacji HTML5, przynajmniej według następujących raportów o błędach:

Chromowni nie wydają się być zwolennikami złagodzenia tej zasady. Bummer.

+1

Interesujący komentarz, ale niestety nie odpowiada na pytanie – mems

7

Trochę za późno, zamiast korzystać z adresu URL danych, używaj atrybutu srcdoc HTML5.

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

Jest przykładem na http://jsfiddle.net/ff3bF/

+2

srcdoc nie działa na IE/Edge. – Seanonymous

+1

To trochę rozczarowuje.Ktoś jest autorem polyfill (https://github.com/jugglinmike/srcdoc-polyfill) – Jamie

3

Odpowiedź podniesionych przez @jamie działa dobrze dla załadunku HTML do iframe i umożliwiając późniejsze Zautomatyzowane interakcję z treścią dokumentu.

XHTML nie jest takie proste.

Atrybut srcdoc wydaje się być ograniczony do HTML, a nie do XHTML.

Praca polega na użyciu adresu URL Blob, który pozwala określić 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); 

Ta technika działa dla przeglądarki Chrome, Firefox i Safari.

Powiązane problemy