第18篇:嵌入外部内容
地图、视频、音乐、天气……网页经常需要展示来自第三方平台的内容。
iframe是最常用的嵌入工具,但它也是一把"双刃剑"——用得好丰富体验,用不好引入安全风险。
学习目标
- 掌握
iframe的基本用法和常用属性 - 理解
sandbox和referrerpolicy等安全属性 - 学会安全地嵌入地图、视频、社交媒体等内容
- 了解
embed和object的适用场景 - 能够评估嵌入第三方内容的安全风险
核心知识点
一、iframe基础
iframe(Inline Frame)在当前页面中嵌入另一个 HTML 页面。
<iframesrc="https://example.com/page.html"width="600"height="400">您的浏览器不支持 iframe。</iframe>iframe核心属性
| 属性 | 作用 | 示例 |
|---|---|---|
src | 嵌入页面的 URL | src="https://..." |
width/height | 尺寸 | width="600" |
title | 可访问性标题(必须) | title="地图" |
frameborder | 边框(HTML5 已废弃,用 CSS) | — |
allowfullscreen | 允许全屏 | allowfullscreen |
loading | 加载策略 | loading="lazy" |
sandbox | 安全沙箱限制 | 见下文 |
referrerpolicy | 控制 referrer 发送 | 见下文 |
<!-- 标准安全写法 --><iframesrc="https://www.youtube.com/embed/VIDEO_ID"width="560"height="315"title="视频标题"allowfullscreenloading="lazy"></iframe>⚠️title 属性是必须的:没有
title的 iframe 对屏幕阅读器用户来说是一个"黑盒",他们不知道里面是什么内容。
二、iframe安全属性详解
sandbox:沙箱限制
sandbox限制 iframe 中页面的权限,防止恶意代码影响父页面。
<!-- 最严格的 sandbox:iframe 中的页面什么都不能做 --><iframesrc="..."sandbox></iframe><!-- 选择性放开权限 --><iframesrc="..."sandbox="allow-scripts allow-same-origin allow-popups"></iframe>sandbox取值
| 值 | 允许的行为 |
|---|---|
allow-scripts | 执行 JavaScript |
allow-same-origin | 被视为同源(可访问 localStorage 等) |
allow-popups | 打开弹出窗口 |
allow-forms | 提交表单 |
allow-top-navigation | 导航父页面(跳转顶部窗口) |
allow-downloads | 下载文件 |
💡安全建议:默认使用空
sandbox(最严格),根据需要逐步放开权限。不要同时设置allow-scripts和allow-same-origin,这相当于没有沙箱。
referrerpolicy:控制 referrer
<!-- 不发送 referrer(保护隐私)--><iframesrc="..."referrerpolicy="no-referrer"></iframe><!-- 只发送来源域名(推荐)--><iframesrc="..."referrerpolicy="origin"></iframe>| 值 | 发送的 referrer |
|---|---|
no-referrer | 不发送 |
origin | 只发送域名(如https://example.com) |
no-referrer-when-downgrade | HTTP→HTTPS 时不发送(默认) |
三、常见嵌入场景
嵌入地图
<!-- 高德地图嵌入 --><iframesrc="https://uri.amap.com/marker?position=116.397428,39.90923&name=天安门"width="600"height="450"title="地图位置"loading="lazy"></iframe>嵌入 Bilibili 视频
<iframesrc="//player.bilibili.com/player.html?bvid=BV1xx411c7mD"width="800"height="600"title="Bilibili 视频"allowfullscreensandbox="allow-scripts allow-same-origin allow-popups"referrerpolicy="no-referrer"></iframe>嵌入 YouTube 视频
<iframesrc="https://www.youtube.com/embed/VIDEO_ID"width="560"height="315"title="YouTube 视频"allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"allowfullscreen></iframe>allow属性
现代 iframe 使用allow属性(替代旧的allowfullscreen等单独属性)来声明需要哪些权限:
<iframesrc="..."allow="fullscreen; camera; microphone"></iframe>| 权限 | 说明 |
|---|---|
fullscreen | 全屏 |
camera | 摄像头 |
microphone | 麦克风 |
autoplay | 自动播放媒体 |
geolocation | 地理位置 |
四、iframe 安全风险
点击劫持(Clickjacking)
攻击者将你的页面嵌入到他的页面中,用透明层覆盖按钮,诱导用户点击。
防御方法:
设置 X-Frame-Options HTTP 响应头(服务器端):
X-Frame-Options: DENY ← 禁止任何页面嵌入 X-Frame-Options: SAMEORIGIN ← 只允许同源页面嵌入使用 CSP frame-ancestors(现代推荐):
Content-Security-Policy: frame-ancestors 'self' https://trusted-site.com
数据窃取
恶意 iframe 可能通过 JavaScript 窃取用户信息。
防御方法:
- 使用
sandbox限制权限 - 不同源 iframe 默认无法访问父页面(同源策略保护)
- 不要同时设置
allow-scripts+allow-same-origin
五、embed和object
除了iframe,还有两个嵌入外部内容的标签。
embed:简单嵌入
<!-- 嵌入 PDF --><embedsrc="document.pdf"type="application/pdf"width="600"height="400"><!-- 嵌入 Flash(已淘汰)--><embedsrc="animation.swf"type="application/x-shockwave-flash">object:功能更丰富的嵌入
<!-- 嵌入 PDF(可指定回退内容)--><objectdata="document.pdf"type="application/pdf"width="600"height="400"><p>您的浏览器不支持 PDF 预览,请<ahref="document.pdf">下载</a>。</p></object><!-- 嵌入视频 --><objectdata="movie.mp4"type="video/mp4"width="640"height="360"><p>视频加载失败。</p></object>三者对比
iframe | embed | object | |
|---|---|---|---|
| 用途 | 嵌入完整网页 | 嵌入插件内容(PDF/Flash) | 嵌入各种资源 |
| 回退内容 | 支持 | 不支持 | 支持 |
| 控制力 | 强(sandbox) | 弱 | 中等 |
| 推荐使用 | ✅ 嵌入网页 | ⚠️ 特定场景 | ⚠️ 需要回退时 |
💡现代建议:
- 嵌入网页 → 用
iframe- 嵌入视频 → 用
video标签(第08篇)- 嵌入 PDF → 用
iframe或链接,避免插件依赖- 嵌入 Flash → ❌ 已淘汰,不要使用
六、完整示例:带地图的联系页面
<!DOCTYPEhtml><htmllang="zh-CN"><head><metacharset="UTF-8"><title>联系我们 - 示例公司</title></head><body><header><h1>联系我们</h1><nav><ahref="/">首页</a></nav></header><main><section><h2>公司地址</h2><address><p>北京市朝阳区 xxx 大厦 10 层</p><p>电话:<ahref="tel:+861012345678">010-1234-5678</a></p></address></section><section><h2>地图导航</h2><!-- 嵌入地图,使用 sandbox 限制权限 --><iframesrc="https://uri.amap.com/marker?position=116.397428,39.90923&name=示例公司"width="100%"height="400"title="公司位置地图"loading="lazy"sandbox="allow-scripts allow-same-origin allow-popups"referrerpolicy="no-referrer"></iframe></section><section><h2>宣传视频</h2><iframesrc="//player.bilibili.com/player.html?bvid=BV1xx411c7mD"width="640"height="360"title="公司宣传视频"allowfullscreenloading="lazy"sandbox="allow-scripts allow-same-origin allow-popups"referrerpolicy="no-referrer"></iframe></section></main><footer><p>© 2024 示例公司</p></footer></body></html>📎 完整代码文件:CODE/18/embed-external.html
动手练习
练习 1:iframe 安全分析
判断以下 iframe 是否安全,并说明原因:
<!-- A --><iframesrc="https://untrusted-site.com"></iframe><!-- B --><iframesrc="https://youtube.com/embed/xxx"sandbox="allow-scripts allow-same-origin"></iframe><!-- C --><iframesrc="https://partner-site.com/widget"sandbox="allow-scripts"referrerpolicy="no-referrer"></iframe>练习 2:创建嵌入页面
创建一个页面,嵌入以下内容:
- 一个地图(高德或百度)
- 一个 Bilibili 或 YouTube 视频
- 每个 iframe 都有
title属性 - 每个 iframe 都有适当的
sandbox限制 - 使用
loading="lazy"延迟加载
练习 3:CSP 防御配置
假设你有一个网站,允许被https://partner.com嵌入,但禁止其他网站。写出对应的 HTTP 响应头:
Content-Security-Policy: frame-ancestors ???常见误区 ⚠️
| 误区 | 真相 |
|---|---|
| “iframe 可以随意嵌入任何网页” | 很多网站通过 X-Frame-Options 或 CSP 禁止被嵌入 |
| “sandbox 会影响 iframe 中的功能” | 是的!这是设计目的。根据需要逐步放开权限 |
| “同时设置 allow-scripts 和 allow-same-origin 很安全” | ❌ 这几乎等于没有沙箱,iframe 中的 JS 可以干任何事 |
| “iframe 中的内容和父页面完全隔离” | 同源 iframe 可以互相访问;跨源受同源策略限制 |
| “title 属性可有可无” | ❌ 对可访问性至关重要,必须设置 |
| “object 可以替代 iframe” | 两者用途不同,不能简单替代 |
| “Flash 仍然可用” | ❌ Flash 已于 2020 年底停止支持,绝对不要使用 |
| “iframe 加载的内容不会影响页面性能” | iframe 会独立加载资源,可能阻塞主页面渲染 |
速查卡片 📋
iframe 安全模板
<iframesrc="https://trusted-site.com/embed"width="600"height="400"title="描述性标题"loading="lazy"sandbox="allow-scripts"referrerpolicy="no-referrer"></iframe>sandbox 权限速查
空 sandbox = 最严格(JS、表单、弹出窗口等都禁止) 常用组合: ├── 纯展示内容:sandbox=""(无 JS) ├── 需要 JS:sandbox="allow-scripts" ├── 需要 JS + 同源:sandbox="allow-scripts allow-same-origin" ⚠️ 慎用 └── 视频播放器:sandbox="allow-scripts allow-same-origin allow-popups allow-presentation"防御点击劫持
# 服务器响应头 X-Frame-Options: DENY # 或 X-Frame-Options: SAMEORIGIN # 现代推荐(CSP) Content-Security-Policy: frame-ancestors 'self' https://trusted-site.comiframe vs embed vs object
| 场景 | 推荐标签 |
|---|---|
| 嵌入网页 | iframe |
| 嵌入视频 | video(优先)或iframe |
| 嵌入地图 | iframe |
| 嵌入 PDF | iframe或链接 |
| 需要回退内容 | object |
iframe 安全 checklist
- 设置了
title属性(可访问性) - 使用
sandbox限制权限 - 非必要不放行
allow-scripts+allow-same-origin - 设置了
referrerpolicy保护隐私 - 非首屏内容使用
loading="lazy" - 服务器端设置了 X-Frame-Options / CSP frame-ancestors
扩展阅读
- MDN: 元素
- MDN: sandbox 属性
- MDN: Clickjacking 防御(英文)
- OWASP: Clickjacking 防护(英文)
📌下一步:外部内容丰富了页面。进入 第19篇:高级语义与微数据,学习让机器更懂你的网页内容。