Iframe contentWindow throws Access Denied error после сокращения document.domain

Я создаю IFRAME динамически следующим образом:

var wrapUpIframe = document.createElement("iframe");
wrapUpIframe.id = 'WrapUpDialog3';
wrapUpIframe.src = 'WrapUpDialog.html';    
document.body.appendChild(wrapUpIframe);

после динамического создания my document.domain сокращается с Servername.dc.com до dc.com,

но когда я пытаюсь получить доступ к contentWindow, я получил сообщение об отказе в доступе:

document.getElementById("WrapUpDialog3").contentWindow.SomeFunction();

Примечание.. Когда я определяю IFRAME статически в HTML, он отлично работает.
Я также попытался изменить свой IFRAME document.domain следующим образом:

WrapUpDialog3.document.domain = dc.com;

Я проверил оба document.domain и мой домен IFRAME, и они оба идентичны.

Что я могу сделать?

Я работаю с IE9.

Ответ 1

Сначала взгляните на правильный ответ из этого сообщения . Мне кажется, что это может быть вашей проблемой.

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

 var frame = $('<iframe>')
.attr('id', 'myIframe')
.addClass('someClass')
.attr('src', 'javascript:(function () {' +'document.open();document.domain=\'myDomain.net\';document.close();' + '})();');
.appendTo($('#someDiv'));

Не уверен, что это актуально, но я также нашел это в Интернете ссылка.

ОК, чтобы ответить на ваш комментарий. Функция javascript не назначает источник, он устанавливает домен документа, который, по-видимому, не выполняется правильно в I.E.

Посмотрите эту ссылку для другого примера и объяснения.

Итак, что бы я попробовал, может быть что-то вроде этого...

var wrapUpIframe = document.createElement("iframe");
wrapUpIframe.id = 'WrapUpDialog3';    
wrapUpIframe.src = setSrc();
document.body.appendChild(wrapUpIframe);

function setSrc(){document.open();document.domain=\'dc.com\';document.close();return 'WrapUpDialog.html';}

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

У меня была аналогичная проблема, но не совсем такая же проблема, поэтому я не могу дать точное решение. Функция, устанавливающая домен документа, была тем, что заставило меня пройти через отказ в доступе.

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

 <script type="text/javascript">
    document.domain = 'dc.com';
  </script>

Я также хотел добавить ссылку для некоторого объяснения явной установки document.domain, который я использовал ранее. Это было полезно для меня в прошлом. В частности, эта цитата...

Явная установка значения указывает на намерение "сотрудничать" с script в другом поддомене (в том же родительском домене).

Дор, у вас может быть проблема с синхронизацией. Я нашел код (здесь), который я только что проверил, который работает для меня. Это гарантирует, что iframe загружен, прежде чем вы попытаетесь получить доступ к контенту contentWindow.

var iframe = document.createElement("iframe");
iframe.src = "WrapUpDialog.html";

if (iframe.attachEvent){
    iframe.attachEvent("onload", function(){
        alert("Local iframe is now loaded.");
    });
} else {
    iframe.onload = function(){
        alert("Local iframe is now loaded.");
    };
}

document.body.appendChild(iframe);

var iframeWindow = iframe.contentWindow || iframe.contentDocument.parentWindow;

Ответ 2

Как вы обслуживаете свои файлы? Вы видите file:/// в адресной строке? Если да, попробуйте использовать ваш код с помощью веб-сервера.

Google Chrome сообщает об ошибке отказа в доступе, если я пытаюсь использовать код file:///, но он работает при обслуживании с локального веб-сервера (т.е. адрес начинается с http://localhost/).

Ответ 3

Поскольку вы еще не приняли ни одного из ответов, у вас, вероятно, все еще есть проблема.

Попробуйте установить document.domain явно на обеих страницах HTML (вы, кажется, делаете это только на одной странице). Это означает, что, как предположил @Vic, вам нужно добавить следующий код javascript в HTML, который включает iframe:

document.domain = 'dc.com';

Это означает, что ваш код будет выглядеть так:

document.domain = 'dc.com';
var wrapUpIframe = document.createElement("iframe");
wrapUpIframe.id = 'WrapUpDialog3';
wrapUpIframe.src = 'WrapUpDialog.html';    
document.body.appendChild(wrapUpIframe);

Затем в самом WrapUpDialog.html (а не на главной странице, потому что тогда вы обойдете систему безопасности!) вам также нужно установить document.domain:

document.domain = dc.com;

Итак, эта строка не будет работать:

WrapUpDialog3.document.domain = 'dc.com';

потому что WrapUpDialog.html сам должен предоставить разрешение своей "родительской" странице для выполнения своего javascript.

Более подробная информация на этой странице: Что делает document.domain = document.domain?.

Финальный намек: попробуйте код, используя разные браузеры: IE9, Firefox, Google Chrome. Это может помочь вам определить, имеете ли вы дело с причудой одного конкретного браузера.