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

相关推荐
天平4 小时前
油猴脚本创建webworker踩坑记录
前端·javascript·typescript
原则猫6 小时前
前端基础大厦
前端
陈随易7 小时前
编程语言级别的Skill市场,AI Agent 的未来形态
前端·后端·程序员
SoaringHeart8 小时前
Flutter进阶:基于 EasyRefresh 的下拉刷新封装 n_easy_refresh_mixin.dart
前端·flutter
IT_陈寒10 小时前
Vite的热更新突然不香了,排查三小时差点砸键盘
前端·人工智能·后端
子兮曰10 小时前
Agency-Agents 深度解析:400+ AI 专家的"梦之队"如何重塑开发工作流
前端·后端·vibecoding
竹林81811 小时前
用 The Graph 查询链上数据实战:从手搓 RPC 到 Subgraph,我的 NFT 项目数据加载快了 10 倍
前端·javascript
妙码生花11 小时前
从 PHP 到 AI + Golang,程序员自救转型手记(十九):点选验证码代码逐行目检
前端·后端·go
Awu122712 小时前
⚡从零开发 Agent CLI(五)实现一个可治理、可扩展的工具系统
前端·人工智能·claude
咪库咪库咪12 小时前
Vue3-生命周期
前端