Skip to content

BizEmbedPage 外链嵌入容器 ​

外链 / 站内页面 iframe 嵌入容器:加载遮罩(loadingText + 旋转图标)、超时兜底(timeout 内未 load → 失败占位 + 重试按钮;CSP / X-Frame-Options 拒嵌的站点无法主动探测,统一触发超时兜底)、右上角悬浮工具条(新窗口打开 / 刷新)、postMessage 双向通信封装(messageOrigin 来源白名单)、keep-alive 地址缓存(LRU,src 切回不重开 loading)、frame / dialog / drawer 三种展示模式。系统内嵌第三方页面、报表大屏、协议文档等场景。

说明:目标站点设置 X-Frame-Options: DENY/SAMEORIGIN 或 CSP frame-ancestors 拒绝被嵌入时,浏览器不会给出可监听的错误事件,iframe 的 load 可能始终不触发——组件统一以「超时占位 + 重试」兜底,请在业务侧提示用户改用工具条「新窗口打开」。demo 中 iframe 的 src 使用 data: URL 内联页面(UTF-8 编码,离线可用)或站点内可嵌页面演示基本形态。

基础用法 ​

报表中心 · 月度概览

load 事件次数:0(点击容器右上角「刷新」工具可再次触发)

frame 模式:容器内 iframe + 加载遮罩 + 右上角悬浮工具条(新窗口打开 / 刷新),src 为 data: URL 内联页(离线可用)。

弹窗模式 ​

visible:false——v-model:visible 双向同步;dialog-width 控制弹层宽度

mode="dialog" 配合 v-model:visible 控制 ElDialog 弹窗内嵌同一容器,dialog-width 控制弹层宽度(首次打开才挂载 iframe)。

抽屉模式 ​

visible:false——dialog-width="480px" 作为抽屉 size

mode="drawer" 配合 v-model:visible 控制抽屉内嵌容器,dialog-width 映射为 drawer 的 size。

超时兜底与重试 ​

第三方系统(演示超时兜底)

timeout=500ms:CSP / X-Frame-Options 拒嵌或网络不可达时 load 不触发,显示失败占位; 点击「重试」重置状态并强制重载。若当前环境可访问且允许嵌入,则正常加载不兜底。

timeout 内 iframe 未触发 load(目标站点拒嵌 / 网络不可达)→ 显示失败占位与「重试」按钮;重试会重置状态并重建 iframe 强制重载。演示地址为 https://example.com:若当前环境可访问且允许嵌入则会正常加载,否则走超时占位。

postMessage 通信 ​

消息通道演示
下行默认 targetOrigin='/'(同源放行);data URL 页面 origin 为 null,默认白名单 ['*'] 放行
内嵌页通过 parent.postMessage(...) 上行,组件经 messageOrigin 白名单校验 event.origin 后抛出 message 事件(data: URL 页面 origin 为 null,默认白名单 ['*'] 放行);下行通过 expose 的 postMessage(data, targetOrigin?) 发送,targetOrigin 默认 '/'(同源放行),跨源场景请传目标站点的具体 origin。生产环境请将 messageOrigin 收紧为已知来源,避免任意页面消息注入。

keep-alive 缓存 ​

按顺序 A → B → C → A:右侧 max-cache=2,C 载入后 A 已被 LRU 淘汰,切回 A 重新出现遮罩

未开 keep-alive(每次切换都重开遮罩)

load 次数:0

keep-alive + max-cache=2(缓存命中直接展示)

load 次数:0(load 仍会计数,差别在于缓存命中不再显示遮罩、不重启超时检测)

keep-alive 记录已加载完成的 src 集合:地址切回已缓存值时不再显示 loading 遮罩、不重启超时检测(iframe 单实例,浏览器 bfcache 负责页面还原);max-cache 控制缓存上限(LRU 淘汰最久未使用地址)。对比左右两侧切回同一地址时的遮罩与 load 次数。

sandbox 安全限制 ​

第三方挂件(sandbox 受限)

sandbox 数组 join(' ') 后写入 iframe sandbox 属性,缺省或空数组则不添加;另:未声明的原生属性(name / id / referrerpolicy / allow 等)会随 attrs 一并透传到 iframe 元素,见「原生属性透传」示例。

sandbox 传入权限 token 列表(join 为 iframe sandbox 属性);缺省或空数组不添加该属性。示例仅授予 allow-scripts:脚本可执行,但 window.open(缺 allow-popups)、表单提交(缺 allow-forms)等能力被拦截。

原生属性透传 ​

(加载后回读 iframe 原生属性)

attrs 同时绑定根元素(class 合并到根与 iframe);事件(如 @load 前的 onClick 等)仅在根元素绑定, 避免与 iframe 冒泡双触发。

未声明的 attrs(name / id / referrerpolicy / allow 等)在绑定根元素的同时,也会过滤事件后透传到 iframe 元素(事件仅在根元素绑定,避免冒泡双触发);可通过 expose 的 getFrame() 读取 iframe 原生元素验证。

自定义加载与失败插槽 ​

自定义加载 / 失败态
#loading 自定义加载态、#error 自定义失败占位(作用域参数 retry 为重试函数)。示例中内联页脚本以同步忙等延迟约 1.5 秒触发 load,便于观察自定义加载态;点击按钮切到拒嵌地址观察自定义失败态。

Props ​

属性名类型默认值说明
srcstring—嵌入页面地址
titlestring''标题:frame 模式标题条 / 弹层模式标题
mode'frame' | 'dialog' | 'drawer''frame'展示模式
v-model:visiblebooleanfalsedialog / drawer 模式弹层开合(frame 模式忽略)
heightnumber | string480iframe 容器高度(number 按 px)
loading-textstring'页面加载中…'加载遮罩文案
timeoutnumber10000加载超时毫秒数,超时显示失败占位;0 关闭检测
sandboxstring[]—iframe sandbox 权限列表;空数组 / 缺省不加属性
message-originstring[]['*']postMessage 来源 origin 白名单('*' 不过滤,生产应收紧)
dialog-widthnumber | string'60%'弹层尺寸:dialog 宽度 / drawer size
keep-alivebooleanfalse缓存已加载地址,src 切回不重开 loading 与超时检测
max-cachenumber5keep-alive 缓存上限(LRU 淘汰)

Events ​

事件名参数说明
load—iframe 加载完成(遮罩消失)
error(payload: { type: 'timeout' })加载超时(目标站点可能拒嵌)
message(data: unknown)收到白名单放行的 postMessage 数据
update:visible(value: boolean)dialog / drawer 模式弹层开合变化

Slots ​

插槽名参数说明
header弹层模式下透传 ElDialog / ElDrawer 头部作用域(含 close)标题区:frame 模式标题条 / 弹层模式头部,缺省显示 title
loading—自定义加载遮罩内容
error(retry: () => void)自定义失败占位,retry 为重试函数
footer—底部区域:frame 模式容器底部 / 弹层模式 footer

Expose ​

名称类型说明
postMessage(data: unknown, targetOrigin?: string) => void向内嵌 iframe 发送 postMessage,targetOrigin 默认 '/'(同源放行,跨源传具体 origin)
reload() => void强制重载(重置加载 / 超时状态并重建 iframe)
getFrame() => HTMLIFrameElement | null获取 iframe 原生元素(未挂载时为 null)