Междоменная связь iframe (postMessage)
предисловие
❝Простыми словами, кросс-доменный относится к взаимным запросам ресурсов между разными доменами, например запросам AJAX, и браузер перехватывает результат ответа в соответствии с политикой одного и того же источника, что является ограничением безопасности, налагаемым браузером на JavaScript. Так называемая гомология относится к одному и тому же доменному имени, протоколу и порту, если один из них отличается, он является междоменным.
❞
фон спроса
Вставьте другой сторонний веб-проект через iframe в веб-проект, нажмите кнопку в стороннем веб-проекте, чтобы вызвать глобальную функцию веб-проекта в режиме реального времени, чтобы открыть глобальное всплывающее окно или выполнить переход по маршруту. В настоящее время существует два проекта. Взаимодействие данных явно нарушает политику одного и того же источника. Метод postMessage в объекте окна, представленный стандартом HTML5, позволяет сценариям из разных источников взаимодействовать асинхронно в ограниченном порядке, позволяя кросс-текстовый документ, мульти -window и обмен сообщениями между доменами.
совместимость
Можно видеть, что postMessage хорошо поддерживается в основных основных браузерах, за исключением браузеров IE с низкими версиями.
грамматика
Для получения дополнительной информации, пожалуйста, нажмите здесьMDN, вот простое объяснение каждого параметра otherWindow.postMessage(сообщение, targetOrigin, [передача]);
- otherWindow: целевое окно (которое вы хотите отправлять междоменные сообщения), например: iframe.contentWindow
- сообщение данные для отправки
- targetOrigin Адрес (URL) целевого окна или строка '*' означает неограниченный, разрешено отправлять любой URL
- передача: необязательный параметр, расширенное использование, здесь не обсуждается, представляет собой строку передаваемых объектов, передаваемых одновременно с сообщением. Право собственности на эти объекты будет передано получателю сообщения, а отправитель больше не сохранит право собственности.
использовать
Предположим, что теперь есть две страницы с разным происхождением, адрес родительской страницы:http://a.index.com, адрес подстраницы:http://b.index.com, родительская страница представляет дочернюю страницу через iframe
<!-- a.index.html -->
<h1>父页面</h1>
<iframe id="iframe" src="http://b.index.com"></iframe>
①Родительская страница отправляет сообщение дочерней странице
const iFrame = document.getElementById('iframe')
<!-- 需要等到iframe中的子页面加载完成后才发送消息,否则子页面接收不到消息 -->
iFrame.onload = function(){
<!-- iFrame.contentWindow获取到iframe的window对象 -->
iFrame.contentWindow.postMessage('父页面发送的消息','http://b.index.com');
}
②Дочерняя страница получает сообщение родительской страницы
有发送就有接收,与postMessage配套使用的就是message事件
window.addEventListener('message',e=>{
<!-- 对消息来源origin做一下过滤,避免接收到非法域名的消息导致的xss攻击 -->
if(e.origin==='http://a.index.com'){
console.log(e.origin) //父页面URL,这里是http://a.index.com
console.log(e.source) // 父页面window对象,全等于window.parent/window.top
console.log(e.data) //父页面发送的消息
}
},false)
③Дочерняя страница отправляет сообщение родительской странице С предыдущей основой нам нужно только помнить, что otherWindow в otherWindow.postMessage — это объект окна целевого окна, в которое вы хотите отправить данные.
window.parent.postMessage('子页面发送的消息','http://a.index.com')
④Родительская страница получает сообщение дочерней страницы Полученная логика связи такая же, как у родитель-потомок и дочерний-родительский
window.addEventListener('message',e=>{
<!-- 对消息来源origin做一下过滤,避免接收到非法域名的消息导致的xss攻击 -->
if(e.origin==='http://b.index.com'){
console.log(e.origin) //子页面URL,这里是http://b.index.com
console.log(e.source) // 子页面window对象,全等于iframe.contentWindow
console.log(e.data) //子页面发送的消息
}
},false)
будь осторожен
- Окно в window.postMessage относится к окну, которому вы хотите отправлять междоменные сообщения (целевое окно, с которым вам нужно общаться), а не к окну его собственного окна.
- На родительской странице: родительская страница отправляет междоменную информацию на дочернюю страницу, а окно — это окно дочерней страницы, на которое указывает iframe, встроенный в родительскую страницу, а именно: iFrame.contentWindow
- На дочерней странице: дочерняя страница хочет, чтобы родительская страница отправляла междоменную информацию, а окно — это окно родительской страницы.Здесь, поскольку дочерняя страница встроена в родительскую страницу, для дочерней страницы окно является топ или родитель.
- Вам нужно дождаться загрузки подстраницы в iframe перед отправкой сообщения, иначе подстраница не получит сообщение
- При прослушивании события сообщения вам необходимо определить источник сообщения