Исключение перекрестного происхождения Javascript в Chrome, но не в Firefox
Недавно я разработал расширение Firefox, которое позволяет мне автоматизировать некоторые действия на нескольких веб-сайтах (в основном получение данных).
Расширение работает хорошо, поэтому в настоящее время я разрабатываю версию расширения для Chrome.
Между расширениями Chrome и Firefox есть некоторые различия, но в основном это один и тот же код, который работает в обоих расширениях.
Проблема
Большинство из них работает, однако у меня проблемы с конкретным веб-сайтом, который хорошо работает с расширением Firefox.
На этом веб-сайте я пытаюсь получить таблицу, которая находится в самом iframe, расположенном в другом iframe.
При доступе ко второму iframe я сталкиваюсь со следующим исключением.
Uncaught SecurityError: Blocked a frame with origin "https://subdomain.domain.fr" from accessing a frame with origin "https://subdomain.domain.fr". The frame requesting access set "document.domain" to "domain.fr", but the frame being accessed did not. Both must set "document.domain" to the same value to allow access
Страница структурирована следующим образом
<iframe id="iframe_centrale" src="/[...]">
[...]
<iframe id="iframe" src="/[...]">
[...]
<table></table>
[...]
</iframe>
[...]
</iframe>
И я пытаюсь получить доступ к iframe следующим образом
var tableElement = null;
var iframe = null;
iframe = document.getElementById('iframe_centrale');
if(null != iframe)
{
iframe = iframe.contentWindow.document.getElementById("iframe");
if(null != iframe)
{
tableElement = iframe.contentWindow.document.evaluate("//table", iframe.contentDocument, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
if((null != tableElement)
{
// Read table
}
}
}
Анализ проблемы
Запущенное исключение обычно встречается при попытке доступа к ресурсу, расположенному в другом домене.
Однако в моем случае оба окна iframe расположены в одном домене, потому что
src
атрибут - относительный URL.
Тот факт, что тот же самый код правильно работает с Firefox, также подтверждает, что я могу получить доступ ко второму iframe.
Больше информации
Еще одна ошибка, с которой я столкнулся, заключается в том, что во время процесса просмотра я заполняю форму, расположенную в iframe, и следующее исключение запускается один раз, однако форма по-прежнему заполняется правильно.
Uncaught DOMException: Blocked a frame with origin "https://subdomain.domain.fr" from accessing a cross-origin frame.
поскольку он находится в цикле наблюдателя мутаций, инструкция может сработать во второй раз, она может объяснить, почему форма заполнена.
После заполнения формы я нажимаю кнопку в iframe, сам в iframe. При нажатии кнопки возникает следующее исключение
Refused to run the JavaScript URL because it violates the following Content Security Policy directive: "script-src 'self'". Either the 'unsafe-inline' keyword, a hash ('sha256-...'), or a nonce ('nonce-...') is required to enable inline execution
Еще раз, щелчок превращается в цикл наблюдателя мутации, поэтому он может быть запущен один раз, а затем работает, но меня перенаправляют на следующую страницу, поэтому щелчок работает.
Вопросов
Почему исключения запускаются с iframe, расположенными в том же домене?
Есть ли другой, чтобы получить доступ ко второму содержимому iframe и действовать с ним с помощью Chrome?
Кто-нибудь знает, почему этот код работает с Firefox, но не с Chrome?
1 ответ
Причина указана в сообщении об ошибке:
The frame requesting access set "document.domain" to "domain.fr", but the frame being
accessed did not. Both must set "document.domain" to the same value to allow access
Политика одинакового происхождения основана на термине " происхождение кортежа ":
scheme
+
host
+
port
+
domain
. Происхождение обычно неизменяемо, можно изменить только домен источника кортежа и только через API (номер порта дополнительно будет сброшен на null).
Один из ваших кадров с происхождением
https://subdomain.domain.fr:443
устанавливает свойство в
https://domain.fr:null
.
Чтобы у него был доступ к другим фреймам на странице, вы должны установить
document.domain = "https://domain.fr"
всем от них. Или, если возможно, вообще не трогайте свойство для любого iframe и главного окна.
Несколько странно, почему ваш код работает в Firefox и не работает в Chrome - последние версии обоих браузеров поддерживают свойства одинаково.
Пожалуйста, обратите внимание, что
document.domain
свойство устарело , поэтому по возможности лучше избегать его использования.
Refused to run the JavaScript URL
Похоже, что политика безопасности контента блокирует
<a href='void(0)'>
конструкции. Это не препятствует переходу по ссылке, просто блокирует выполнение javascript.