Object 与 Embed 元素
一、object 与 embed 概述
1.1 历史背景
<object> 和 <embed> 是浏览器用于嵌入外部资源的老牌元素。在 Flash 时代,这些元素用于嵌入 Flash 动画。虽然 Flash 已经退出历史舞台,但这些元素在嵌入 PDF、SVG、以及其他插件内容时仍然有用。
1.2 基本概念
| 元素 | 特点 | 典型用途 |
|---|---|---|
<object> |
通用外部资源嵌入,支持后备内容 | PDF、插件 |
<embed> |
单一用途嵌入,自包含 | 旧版插件、PDF |
<!-- object 嵌入 PDF -->
<object
type="application/pdf"
data="/document.pdf"
width="600"
height="500">
<p>无法显示 PDF。<a href="/document.pdf">下载 PDF</a></p>
</object>
<!-- embed 嵌入 PDF -->
<embed
src="/document.pdf"
type="application/pdf"
width="600"
height="500" />
二、object 元素详解
2.1 核心属性
| 属性 | 作用 |
|---|---|
data |
资源 URL |
type |
MIME 类型 |
width / height |
尺寸 |
name |
浏览上下文名称 |
form |
关联的表单 |
<object
type="image/svg+xml"
data="/image.svg"
width="400"
height="300">
<p>Your browser doesn't support SVG.</p>
</object>
2.2 后备内容
<object> 支持丰富后备内容,当资源无法加载时显示:
<object type="video/webm" data="/video.webm" width="640" height="480">
<!-- 后备内容 -->
<div class="fallback">
<p>无法播放视频。</p>
<img src="/video-poster.jpg" alt="视频封面" />
<p><a href="/video.webm">下载视频文件</a></p>
</div>
</object>
2.3 与表单关联
<form id="myform" action="/upload" method="POST">
<input type="file" name="document" />
</form>
<object
id="pdfviewer"
type="application/pdf"
data="/doc.pdf"
width="600"
height="500"
form="myform">
</object>
三、embed 元素
3.1 简单直接
<embed> 是自包含元素,不需要闭合标签,直接嵌入外部内容:
<!-- 嵌入 PDF -->
<embed src="/document.pdf" type="application/pdf" width="600" height="400" />
<!-- 嵌入 SVG -->
<embed src="/graphic.svg" type="image/svg+xml" width="400" height="300" />
<!-- 嵌入旧版插件(Flash 等)-->
<embed src="/movie.swf" type="application/x-shockwave-flash" width="400" height="300" />
3.2 必需属性
<!-- src 和 type 通常是必需的 -->
<!-- 没有后备内容——如果无法加载则显示空白或错误 -->
<embed src="/content.pdf" type="application/pdf" />
四、与 iframe、img 的对比
4.1 选择指南
| 场景 | 推荐元素 |
|---|---|
| 嵌入网页(可交互) | <iframe> |
| 嵌入图片 | <img> 或 <picture> |
| 嵌入文档(PDF) | <object> 或 <embed> |
| 嵌入插件内容 | <object> 或 <embed> |
4.2 iframe vs object
<!-- iframe:独立浏览上下文 -->
<iframe src="/page.html" width="600" height="400"></iframe>
<!-- object:外部资源,不是独立页面 -->
<object data="/page.html" width="600" height="400"></object>
关键区别:iframe 创建新的浏览上下文(new browsing context),有独立的 document、sessionStorage;object 只是把外部资源嵌入当前页面。
4.3 img vs object
<!-- img:图片的最佳选择 -->
<img src="/photo.jpg" alt="照片" />
<!-- object:用于非图片资源 -->
<object type="image/svg+xml" data="/icon.svg"></object>
五、实际应用场景
5.1 PDF 嵌入
<!-- 方法一:object(推荐有后备)-->
<object
data="/document.pdf"
type="application/pdf"
width="100%"
height="600"
standby="加载中...">
<div class="pdf-fallback">
<p>您的浏览器不支持 PDF 预览。</p>
<a href="/document.pdf" download>下载 PDF</a>
</div>
</object>
<!-- 方法二:embed(简单场景)-->
<embed
src="/document.pdf"
type="application/pdf"
width="100%"
height="600" />
5.2 PDF 嵌入的现代替代
<!-- 现代方法:使用 PDF.js -->
<canvas id="pdf-canvas"></canvas>
<script src="/pdfjs/pdf.min.js"></script>
<script>
const canvas = document.getElementById('pdf-canvas');
const ctx = canvas.getContext('2d');
pdfjsLib.getDocument('/document.pdf').then((pdf) => {
pdf.getPage(1).then((page) => {
const viewport = page.getViewport({ scale: 1.5 });
canvas.height = viewport.height;
canvas.width = viewport.width;
page.render({ canvasContext: ctx, viewport });
});
});
</script>
5.3 SVG 嵌入
<!-- object 嵌入带后备 -->
<object
type="image/svg+xml"
data="/chart.svg"
width="600"
height="400">
<img src="/chart-fallback.png" alt="销售图表" />
</object>
<!-- embed 嵌入 -->
<embed src="/interactive.svg" type="image/svg+xml" width="600" height="400" />
六、注意事项
6.1 安全性
<!-- object 和 embed 可能引发安全风险 -->
<!-- 考虑使用 sandbox 属性或 CSP -->
<!-- PDF 嵌入可能需要插件——现代浏览器通常有内置 PDF viewer -->
6.2 性能
<!-- 嵌入大型 PDF/SWF 会影响页面性能 -->
<!-- 考虑懒加载或使用专用查看器 -->
<object data="/large.pdf" type="application/pdf" loading="lazy" />
七、面试高频问题
Q: object 和 iframe 有什么区别?
回答要点:iframe 创建独立的浏览上下文,有自己的 document、sessionStorage 和历史记录;object 只是将外部资源作为对象嵌入当前页面,共享父页面的上下文。iframe 适合嵌入独立页面,object 适合嵌入文件或资源。
Q: 什么时候用 object 而不是 img 嵌入图片?
回答要点:img 是嵌入图片的标准方式。当需要后备内容或嵌入 SVG 等需要脚本处理的图形时使用 object。img 更轻量、语义更清晰、浏览器优化更好。
Q: Flash 退出后,object 和 embed 还有实际用途吗?
回答要点:仍然适用于 PDF 嵌入(虽然现代浏览器有内置 PDF viewer)、旧版插件内容、以及需要后备内容的外部资源。但对于大多数场景,iframe 和专用库(如 PDF.js)更合适。