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

相关推荐
qq_589666054 小时前
TypeScript 完整入门教程
前端·javascript·typescript
用户059540174467 小时前
LLM对话记忆测试踩坑实录:手工回归30分钟,自动化后2分钟发现3个隐藏Bug
前端·css
Ashley的成长之路9 小时前
前端性能优化实战手册·第2篇:资源加载策略全解
前端·性能优化·资源加载·http/3·性能优化实战·资源加载优化
浅水壁虎9 小时前
vue基础(第二章 )
前端·javascript·vue.js
界面开发小八哥9 小时前
界面控件DevExtreme v26.1新版亮点——支持Angular 22
前端·javascript·angular.js·devexpress·ui开发·devextreme
Getflare9 小时前
前端 + UI 设计 + AI:这不是三个工种,是一个新三角能力模型(附自检清单)
前端·人工智能·ui
oil欧哟9 小时前
我做了一个 Vibe Coding 术语学习站:VibeHub
前端·ai·agent·独立开发·vibe coding
审小匠OpenCPAi10 小时前
银行流水核查怎么自动化?单边匹配、双向勾稽与图聚类异常检测的工程对比
java·前端·人工智能·python·审计
Revolution6110 小时前
一个公共表格组件,是怎么一步步失控的
前端·前端工程化