Программный доступ к 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, по крайней мере, согласно следующим сообщениям об ошибках:
- https://bugs.webkit.org/show_bug.cgi?id=17352
- https://code.google.com/p/chromium/issues/detail?id=58999
разработчики 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.