iframe实践

iframe 接入

使用<iframe>标签定义嵌入窗口,标签属性包括以下:

  • src:目标页面URL
  • width/height:展示框架尺寸
  • scrolling:控制滚动条显示
  • frameborder:定义边框样式
html 复制代码
<iframe src="https://example.com/module" width="100%" height="400" scrolling="auto"></iframe>

预加载优化

可以通过隐藏iframe (style="display: none")预加载资源,提升用户交互响应速度。


iframe 父子窗口通信(纯前端)

url 传参
javaScript 复制代码
// 父窗口
<iframe 
    src="https://example.com/module?id=${params.id}" 
    width="100%" 
    height="400" 
    scrolling="auto"
></iframe>

// 子窗口
let params = [];

if (window.location.search) {
    const params = window.location.search.split('?')[1].split('&')

    params.forEach((item) => {
        const [key, value] = item.split('=')
        params.push({
            key,
            value
        })
    })
}

postMessage 传参

postMessageiframe跨域通信的 API

父窗口向子窗口传参
javaScript 复制代码
// 父窗口发送
const iframe = document.getElementById('iframe');
iframe.onload = () => {
    iframe.contentWindow.postMessage(
        {
            action: 'updateTheme',
            theme: 'dark'
        },
        'http://child-domain.com'
    )
}

// 子窗口接收
window.addEventListener('message', (event) => {
    if (event.origin !== 'https://parent-domain.com') return;
    if (event.data.action === 'updateTime') {
        document.body.className = event.data.theme;
    }
})
子窗口向父窗口传参
javaScript 复制代码
// 子窗口发送
window.parent.postMessage(
    { status: 'loaded', height: document.body.scrollHeight },
    'https://parent-domain.com'
)

// 父窗口接收
window.addEventListener('message', (event) => {
    if (event.origin !== 'https://child-domain.com') return;
    if (event.data.status === 'loaded') {
        iframe.style.height = `${event.data.height}px`
    }
})

基于 DOM 操作的数据交互

通过获取iframeDOM 节点,直接读取或修改子窗口元素的属性/内容,适用于同域场景/可修改iframe源码的情况。

父窗口向子窗口传参

通过window.frames获取iframe对象,再访问其document属性操作DOM元素。

javaScript 复制代码
// 获取子窗口中的元素,将数据写入
const iframe = window.frames['iframeId'];
const childElement = iframe.document.getElementById('targetElement');
childElement.innerText = '父窗口传递的数据';

// 通过 contentDocument 属性直接访问
const childDoc = document.getElementById('iframeId').contentDocument;
子窗口向父窗口传参

子窗口通过window.parent对象访问父窗口的DOM元素。

javaScript 复制代码
// 获取父窗口 DOM 元素
const parentElement = window.parent.document.getElementById('parentElement');

// 读取父窗口数据
const data = parentElement.getAttribute('data-info');

Hash 值传递数据

Hash的修改不会触发页面刷新 ,会记录在浏览历史 中,允许跨域页面通过监听hashchange事件捕获Hash变化,从而实现单项数据传递

javaScript 复制代码
// 父窗口修改 hash
const iframe = document.getElementById('myIframe');
iframe.src = iframe.src.split('#')[0] + "#userToken=assds123&action=update";

// 子窗口监听接收值
window.addEventListener('hashchange', () => {
    const hashData = window.location.hash.substring(1);
    const params = new URLSearchParams(hashData);
    
    const data = {
        userToken: params.get('userToken'),
        action: params.get('action')
    }
})

if (window.location.hash) {
    window.dispatchEvent(new Event('hashchange'))
}

iframe 中 localStorage 和 sessionStorage 使用

只有当父子窗口的协议、域名、端口完全一致即同源 ,才能直接共享localStoragesessionStorage数据。


cookieiframe 中的使用也是遵照同源 的原则,不同源的父子窗口只能各自使用取自己的 cookie

不同源的 cookie 就类似上述图片,各自只能获取,修改自己的 cookie ,后台种植 cookie 也是自己域下的。

如果后端在 iframe 子窗口中种植 cookieSameSite 没有设置为 None ,就会报下面这种错误同时 cookie 无法正常使用。

这种情况,就需要后端在种植 cookie 的同时,将 Same-Site 设置为 None

相关推荐
珍宝商店1 小时前
前端老旧项目全面性能优化指南与面试攻略
前端·面试·性能优化
bitbitDown1 小时前
四年前端分享给你的高效开发工具库
前端·javascript·vue.js
gnip2 小时前
实现AI对话光标跟随效果
前端·javascript
脑花儿3 小时前
ABAP SMW0下载Excel模板并填充&&剪切板方式粘贴
java·前端·数据库
lumi.4 小时前
Vue.js 从入门到实践1:环境搭建、数据绑定与条件渲染
前端·javascript·vue.js
二十雨辰4 小时前
vue核心原理实现
前端·javascript·vue.js
影子信息4 小时前
[Vue warn]: Error in mounted hook: “ReferenceError: Jessibuca is not defined“
前端·javascript·vue.js
卷Java4 小时前
CSS模板语法修复总结
java·前端·css·数据库·微信小程序·uni-app·springboot
gihigo19985 小时前
在CentOS上配置SVN至Web目录的自动同步
前端·svn·centos
珍宝商店5 小时前
优雅的 async/await 错误处理模式指南
开发语言·前端·javascript