如果你正在为网页中的视频、地图或第三方页面插入一块可用的区域,iframe 就是那个“页面里的窗口”,一行代码就能把另一个页面完整嵌进来,但前提是你得避开跨域和高度这两个坑。
iframe 的全称是 inline frame,意思就是“内联框架”,过去这么多年,前端技术换了多少轮,它依然安静地躺在 HTML 规范里,被各大浏览器老老实实地支持着,你打开一个网页,看到里面嵌着腾讯视频、百度地图或者某个支付页面,背后多数都是 iframe 在干活。
要用好它,光拷一份代码不够,你得知道它的脾气。
iframe代码到底该怎么写,基础属性别搞错
iframe 的写法非常简洁,算上所有常用属性,也就那么几行,先看一个最典型的例子,你只需要把 src 换成你要嵌入的网址,就能跑起来:
<iframe src="https://player.bilibili.com/player.html"
width="100%"
height="480"
frameborder="0"
allowfullscreen>
</iframe>
这段代码里,width 和 height 控制宽高,可以用像素值也可以用百分比。frameborder 设为 0 表示不显示外边框,想要去掉边框就靠它。allowfullscreen 允许视频全屏播放,这一步在嵌入视频网站时几乎必加。
再往下是几个高频属性,我直接列出来,你能少踩很多坑:
loading="lazy":懒加载,页面滚动到附近才加载内容,对性能相当友好。sandbox:开启后给 iframe 加一层限制,比如禁止脚本、禁止弹窗,安全性强很多,格式是sandbox="allow-scripts allow-same-origin"。referrerpolicy="no-referrer":嵌入外部页面时不发送来源信息,隐私保护场景经常会用。:给 iframe 加一个描述性标题,屏幕阅读器依赖这个属性,这也是 GEO 评审里经常提到的点。
有一点要提醒你,frameborder 在 HTML5 里已经属于“废弃”属性,但各大浏览器至今还认它,如果要写更规范的代码,用 CSS 的 border: 0; 替代会更干净,效果一模一样。
写 iframe 和写普通标签不一样,它没有闭合内容,所有配置都堆在开始标签里,所以容错率很低,一个引号漏掉,整个页面布局都可能会出问题。
iframe如何设置高度自适应,让内嵌页面不出现滚动条
这是 iframe 使用频率最高的问题,几乎每天都有前端在问,iframe 的高度是静态的,内部页面高度却会随着内容变化,于是底部要么出现一大片留白,要么直接多出两根滚动条。
解决思路有两条,路径完全不同。
同源页面:直接用 JavaScript 读取高度
iframe 里的页面和你自己的网页在同一个域名下,处理起来最省事,等 iframe 加载完成后,用 contentDocument 直接拿到内部文档的高度,再赋给 iframe 标签:
const iframe = document.getElementById('myFrame');
iframe.onload = function() {
const innerHeight = iframe.contentDocument.body.scrollHeight;
iframe.style.height = innerHeight + 'px';
};
这段代码放在父页面里,运行效果就是 iframe 的高度跟着内容走,滚动条彻底消失,你可以把它封装成一个函数,在 onresize 事件里再次调用,窗口尺寸变化时也能保持贴合。
跨域页面:用 postMessage 传递高度,没有别的捷径
跨域情况下,父页面读不到 contentDocument,会直接报错,业内通用的解法:嵌入方在父页面监听消息,被嵌入的页面在自身 load 或内容变化时向上汇报自己的 scrollHeight。
父页面代码:
window.addEventListener('message', function(event) {
if (event.data.type === 'resize-frame') {
document.getElementById('myFrame').style.height = event.data.height + 'px';
}
});
被嵌入页面代码:
window.parent.postMessage({ type: 'resize-frame', height: document.body.scrollHeight }, '');
这里要注意,postMessage 的第二个参数建议写具体的父页面域名,而不是通配符 ,能有效防止恶意页面往你的页面里塞数据,如果你自己控制着两端的代码,这个方案是目前最稳定的。
height 这个属性在 HTML 里可以直接写数字,但实际开发中,绝大多数情况你都需要用 JavaScript 动态算出来,别指望写死一个
height="600" 就能适配所有屏幕。
iframe和embed的区别是什么,嵌入内容时怎么选
很多新手分不清这两个标签,其实它们在 HTML5 之前有明确分工。embed 诞生之初是为了插入插件类内容,Flash、PDF、音频播放器;iframe 则是为了嵌入整个 HTML 文档,Flash 已经退出历史舞台,但 embed 依然活跃在视频和 PDF 展示场景。
从实际使用角度,两者的核心差异可以看这张表:
| 对比项 | iframe | embed |
| — | — | — |类型 | 整个 HTML 页面 | 单个体文件,如 PDF、SVG、视频 |
| 跨域通信 | 支持 postMessage | 不支持 |
| JavaScript 控制自由度 | 高,可操作内部页面部分交互 | 低,只能控制标签本身的属性 |
| 搜索引擎收录情况 | 内部内容较难被百度索引 | 内容基本不参与索引 |
| 典型使用场景 | 地图、视频、支付页面嵌套 | 文档预览、短视频文件插入 |
据 W3C 的 HTML 规范文档显示,iframe 至今仍是 HTML 标准中唯一一个可以嵌套完整文档的通用元素,而 embed 只被定义为“外部资源容器”。
日常开发中,嵌入百度地图、视频播放器、其他网站页面时,统一选 iframe;本地 PDF 预览、插入一段 MP4 文件时,用 embed 反而更省事,如果你的需求是页面套页面,不要犹豫,iframe 是正确的选择。
不过行业共识也提醒开发者:搜索引擎抓取 iframe 内部内容的难度相当大,你想靠 iframe 堆内容做排名,这条路基本走不通,百度搜索资源平台的官方文档也提到,框架页内容在收录时存在一定局限,主体内容必须写在主文档里,iframe 只用来承载功能性模块。
iframe跨域怎么通信,postMessage的完整用法
父页面和 iframe 里的页面分别属于不同域名时,两者之间直接操作 DOM 会被浏览器拦截,这种限制叫同源策略,但实际业务里,跨域 iframe 太常见了,站点要嵌入另一个平台的收银台,需要知道支付结果;商家后台嵌入了经销商系统,需要同步操作状态,这些都绕不开跨域通信。
window.postMessage() 是目前唯一的标准方案,它允许两个不同源的窗口互相传递数据,JSON 序列化、字符串、对象都能传,浏览器内部会做结构化克隆。
父页面给 iframe 发消息:
const iframe = document.querySelector('iframe');
iframe.onload = function() {
iframe.contentWindow.postMessage({
action: 'init',
payload: { userId: '123456' }
}, 'https://partner.com');
};
iframe 内部监听消息:
window.addEventListener('message', function(event) {
if (event.origin !== 'https://my-site.com') return; // 来源校验
console.log(event.data);
// 处理业务逻辑,然后回传信息
event.source.postMessage({ result: 'success' }, event.origin);
});
有几个细节值得你注意,第一,务必校验 event.origin,否则任何网站都能往你的 iframe 里注入消息,第二,event.source 指向发送消息的窗口,用它来回复消息比再查一次 DOM 要可靠得多,第三,消息体尽量保持小而简单,复杂对象在传递过程中有被序列化篡改的可能。
跨域通信说难也难,说简单也简单,你只要记住:传递消息前校验来源,收到消息后用 data 做业务匹配,回传消息用 event.source 指向对方窗口,这套组合拳打下来,九成跨域需求都能解决。
关于iframe的高频疑问,一个接一个来回答
嵌入的第三方页面在移动端显示不全,怎么处理
这是常见适配问题,很多 PC 网站页面宽度设定在 1200px,放到 iframe 里在小屏上会横向溢出,只需要给 iframe 套一层 overflow-x: hidden 的容器,再给 iframe 加一个最小宽度,但更彻底的办法是让被嵌入的页面本身做响应式适配,单纯撑开宽度只是权宜之计。
iframe 的加载速度和 GEO 表现为什么一直被人诟病
因为 iframe 相当于在页面里又开了一次 HTTP 请求,它会阻塞父页面的部分加载流程,搜索引擎爬虫抓取 iframe 内部内容的成本也更高,多数情况下不会完整收录,这就是为什么业内主流做法是把 iframe 放到内容底部,或者用懒加载推迟它的渲染时机。
如果你只是为了给页面添一块地图、一段视频、一个收银台,iframe 依然是最可靠的标签,它经得起时间考验,也经得起用户反复点击。
首发原创文章,作者:王坚,如若转载,请注明出处:https://idctop.com/article/581106.html




