Политика того же происхождения
Вы не можете получить доступ к <iframe>
другому источнику, используя JavaScript, это было бы огромным недостатком безопасности, если бы вы могли это сделать. Для браузеров с политикой одного источника блокируют сценарии, пытаясь получить доступ к кадру с другим источником .
Источник считается другим, если хотя бы одна из следующих частей адреса не поддерживается:
<protocol>://<hostname>:<port>/...
Протокол , имя хоста и порт должны совпадать с вашим доменом, если вы хотите получить доступ к фрейму.
ПРИМЕЧАНИЕ. Известно, что Internet Explorer строго не следует этому правилу, подробности см. Здесь .
Примеры
Вот что произойдет при попытке получить доступ к следующим URL-адресам из http://www.example.com/home/index.html
URL RESULT
http://www.example.com/home/other.html -> Success
http://www.example.com/dir/inner/another.php -> Success
http://www.example.com:80 -> Success (default port for HTTP)
http://www.example.com:2251 -> Failure: different port
http://data.example.com/dir/other.html -> Failure: different hostname
https://www.example.com/home/index.html:80 -> Failure: different protocol
ftp://www.example.com:21 -> Failure: different protocol & port
https://google.com/search?q=james+bond -> Failure: different protocol, port & hostname
Временное решение
Несмотря на то, что политика одного и того же источника блокирует доступ сценариев к содержимому сайтов с другим источником, если вы владеете обеими страницами, вы можете обойти эту проблему, используя window.postMessage
ее относительное message
событие для отправки сообщений между двумя страницами, например:
На вашей главной странице:
let frame = document.getElementById('your-frame-id');
frame.contentWindow.postMessage(/*any variable or object here*/, 'http://your-second-site.com');
Вторым аргументом postMessage()
может быть '*'
указание на отсутствие предпочтений относительно источника назначения. По возможности всегда следует указывать целевое происхождение, чтобы избежать разглашения данных, которые вы отправляете на любой другой сайт.
В вашем <iframe>
(содержится на главной странице):
window.addEventListener('message', event => {
// IMPORTANT: check the origin of the data!
if (event.origin.startsWith('http://your-first-site.com')) {
// The data was sent from your site.
// Data sent with postMessage is stored in event.data:
console.log(event.data);
} else {
// The data was NOT sent from your site!
// Be careful! Do not use it. This else branch is
// here just for clarity, you usually shouldn't need it.
return;
}
});
Этот метод можно применять в обоих направлениях , создавая слушателя на главной странице и получая ответы из фрейма. Та же логика также может быть реализована во всплывающих окнах и в основном в любом новом окне, сгенерированном главной страницей (например, с помощью window.open()
), без каких-либо различий.
Отключение политики того же происхождения в вашем браузере
На эту тему уже есть несколько хороших ответов (я только что нашел их в поиске), поэтому для браузеров, где это возможно, я приведу относительный ответ. Однако помните, что отключение политики одного источника повлияет только на ваш браузер . Кроме того, запуск браузера с отключенными настройками безопасности того же источника предоставляет любому веб-сайту доступ к ресурсам из разных источников, поэтому это очень небезопасно и НИКОГДА не следует делать, если вы точно не знаете, что делаете (например, в целях разработки) .
Access-Control-Allow-Origin
не применяется к iFrames, только к XHR, Fonts, WebGL иcanvas.drawImage
. Я считаю,postMessage
что это единственный вариант.