Программный доступ к iframe, использующему URI данных в качестве источника

Я создаю iframe программно, используя URI "data":

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

этот фрейм загружается нормально, но кажется, что работа с iframe программно попадает в междоменные проверки безопасности.

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

выдает ошибку в Chrome и Safari:

небезопасная попытка JavaScript получить доступ к кадру с URL данные: text / html; charset=utf-8,... из кадра с URL http://... Этот фрейм, запрашивающий доступ, имеет протокол "http", фрейм бытие доступ имеет протокол ". Протоколы должны совпадать.

вот скрипка, показывающая ошибку безопасности:http://jsfiddle.net/bhGcw/4/

Firefox и Opera не выбрасывают это исключение и позволяют изменять содержимое iframe. Похоже, Webkit видит пустой протокол для URI данных и видит это как нарушение междоменного.

есть ли способ обойти это?

3 ответов


немного поздно, как насчет вместо использования URL-адреса данных вы используете атрибут 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>

есть пример в http://jsfiddle.net/ff3bF/


похоже, что Webkit делает простое сравнение строк в их код проверки домена:

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

    ...
}

похоже, что Chromium является более строгим, чем спецификация HTML5, по крайней мере, согласно следующим сообщениям об ошибках:

разработчики Chromium, похоже, не в пользу об ослаблении этого правила. Лентяй.


ответ, предложенный @jamie, хорошо работает для загрузки HTML в iframe и последующего программного взаимодействия с содержимым документа.

XHTML не так просто.

на srcdoc атрибут, похоже, ограничен HTML, а не XHTML.

работа вокруг заключается в использовании Blob URL, который позволяет 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);

этот метод работает, по крайней мере, для Chrome, Firefox и Safari.