Політика одного походження
Ви не можете отримати доступ до <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
це єдиний варіант.