从对象到 iframe — 其他嵌入技术
现在您应该已经非常熟悉如何将内容嵌入到网页中,包括图像、视频和音频。在这一点上,我们想稍微偏离一下,看看一些允许您将各种内容类型嵌入到网页中的元素:<iframe>
、<embed>
和 <object>
元素。<iframe>
用于嵌入其他网页,另外两个允许您嵌入外部资源,例如 PDF 文件。
嵌入技术的简史
很久以前在网页上,使用 **框架** 创建网站很流行 — 网站的小部分存储在单独的 HTML 页面中。这些嵌入在一个名为 **框架集** 的主文档中,允许您指定屏幕上每个框架所占的区域,就像调整表格的列和行一样。在 90 年代中期到后期,这些被认为是酷炫的顶峰,并且有证据表明将网页分割成更小的块对于下载速度来说更好 — 特别是在当时网络连接速度非常慢的情况下,这一点尤为明显。然而,它们确实存在许多问题,这些问题远远超过了随着网络速度加快带来的任何好处,所以您现在已经看不到它们被使用了。
不久之后(90 年代后期,2000 年代初期),插件技术变得非常流行,例如 Java Applet 和 Flash — 这些允许网页开发者将丰富的网页内容嵌入网页中,例如视频和动画,这些内容仅靠 HTML 无法实现。嵌入这些技术是通过诸如 <object>
之类的元素来实现的,以及使用较少的 <embed>
,它们当时非常有用。从那时起,由于许多问题,它们已经过时,包括无障碍、安全、文件大小等等。如今,主流浏览器已经停止支持 Flash 等插件。
最后,<iframe>
元素出现了(以及其他嵌入内容的方式,例如 <canvas>
、<video>
等)。这提供了一种将整个网页文档嵌入到另一个网页中的方法,就好像它是一个 <img>
或其他类似元素一样,并且今天经常被使用。
现在历史课已经结束,让我们继续看看如何使用其中的一些。
主动学习:经典嵌入用例
在本文中,我们将直接跳到主动学习部分,以便立即让您对嵌入技术究竟有什么用处有一个真实的了解。网络世界非常熟悉 YouTube,但许多人并不知道它提供的一些共享功能。让我们看看 YouTube 如何允许我们使用 <iframe>
将视频嵌入到我们喜欢的任何页面中。
- 首先,转到 YouTube 并找到您喜欢的视频。
- 在视频下方,您会找到一个 *分享* 按钮 — 选择它以显示共享选项。
- 选择嵌入按钮,您将获得一些
<iframe>
代码 - 复制它。 - 将其插入下面的输入框中,然后查看输出中的结果。
为了获得加分,您也可以尝试在示例中嵌入一个谷歌地图
- 进入谷歌地图并找到您喜欢的地图。
- 点击 UI 左上角的“汉堡菜单”(三个水平线)。
- 选择分享或嵌入地图选项。
- 选择嵌入地图选项,这将为您提供一些
<iframe>
代码 - 复制它。 - 将其插入下面的输入框中,然后查看输出中的结果。
如果您犯了错误,您可以随时使用重置按钮将其重置。如果您真的卡住了,请按显示解决方案按钮查看答案。
iframes 的详细介绍
所以,这很简单也很有趣,对吧?<iframe>
元素旨在让您将其他网页文档嵌入当前文档中。这非常适合将您可能无法直接控制且不想自己实现的第三方内容(例如来自在线视频提供商的视频、Disqus 等评论系统、来自在线地图提供商的地图、广告横幅等)整合到您的网站中。即使您在本课程中一直使用的实时可编辑示例也是使用<iframe>
实现的。
在深入研究使用<iframe>
元素之前,需要了解一些安全问题。假设您想在您的一个网页中使用<iframe>
元素包含 MDN 词汇表,您可能会尝试以下代码示例。如果您将以下代码添加到您的一个页面中,您可能会惊讶地看到错误消息而不是词汇表页面
<head>
<style>
iframe {
border: none;
}
</style>
</head>
<body>
<iframe
src="https://mdn.org.cn/en-US/docs/Glossary"
width="100%"
height="500"
allowfullscreen
sandbox>
<p>
<a href="/en-US/docs/Glossary">
Fallback link for browsers that don't support iframes
</a>
</p>
</iframe>
</body>
如果您查看浏览器的控制台,您会看到以下错误消息
Refused to display 'https://mdn.org.cn/' in a frame because it set 'X-Frame-Options' to 'deny'.
下面的安全部分将更详细地介绍为什么您会看到此错误,但首先,让我们看一下我们的代码在做什么。
该示例包含使用<iframe>
所需的必要条件
border: none
-
如果使用,则
<iframe>
在没有周围边框的情况下显示。否则,默认情况下,浏览器会在周围显示<iframe>
边框(这通常是不可取的)。 allowfullscreen
-
如果设置,则可以使用全屏 API(有点超出本文的范围)将
<iframe>
置于全屏模式。 src
width
和height
-
这些属性指定您希望 iframe 的宽度和高度。
sandbox
-
此属性(在比其他
<iframe>
功能更现代的浏览器中工作,例如 IE 10 及更高版本)请求提高的安全设置;我们将在下一节中详细介绍。
注意:为了提高速度,最好在主要内容加载完成后使用 JavaScript 设置 iframe 的src
属性。这使您的页面更快地可用,并减少了您的官方页面加载时间(一个重要的SEO指标)。
安全问题
上面我们提到了安全问题——现在让我们更详细地讨论一下。我们不希望您第一次就完全理解所有这些内容;我们只是想让您了解这个问题,并提供一个参考,以便您在获得更多经验并开始考虑在您的实验和工作中使用<iframe>
时可以返回查看。此外,没有必要害怕而不用<iframe>
——您只需要小心。继续阅读…
浏览器制造商和 Web 开发人员已经从痛苦的经验中了解到,如果有人试图恶意修改您的网页或欺骗人们做他们不想做的事情(例如透露敏感信息,如用户名和密码),iframe 是网络上恶意人士(通常被称为黑客,或者更准确地说,破解者)攻击的常见目标(官方术语:攻击载体)。因此,规范工程师和浏览器开发人员已经开发出各种安全机制,使<iframe>
更加安全,并且还有一些最佳实践需要考虑——我们将在下面介绍其中一些。
注意:点击劫持是一种常见的 iframe 攻击,黑客将不可见的 iframe 嵌入您的文档(或将您的文档嵌入他们自己的恶意网站)并使用它来捕获用户的交互。这是一种常见的误导用户或窃取敏感数据的方法。
首先,让我们举一个简单的例子——尝试将我们上面显示的先前示例加载到您的浏览器中——您可以在 GitHub 上找到它(查看源代码)。您可能不会看到您预期的页面,而是会看到一些类似“我无法打开此页面”的消息,如果您查看浏览器开发者工具中的控制台,您会看到一条消息告诉您原因。在 Firefox 中,您将看到类似“在框架中加载“https://mdn.org.cn/en-US/docs/Glossary”被“X-Frame-Options”指令设置为“DENY”所拒绝的消息。这是因为构建 MDN 的开发人员在提供网站页面的服务器上包含了一个设置,以禁止将它们嵌入<iframe>
中(请参阅下面的配置 CSP 指令)。这是有道理的——整个 MDN 页面嵌入其他页面中实际上毫无意义,除非您想做一些事情,例如将它们嵌入您的网站并声称它们是您的——或者尝试通过点击劫持窃取数据,这两者都是非常糟糕的事情。此外,如果每个人都开始这样做,所有额外的带宽将开始让 Mozilla 损失很多钱。
仅在必要时嵌入
有时嵌入第三方内容是有意义的——例如 YouTube 视频和地图——但如果您只在完全必要时才嵌入第三方内容,您可以避免很多麻烦。网络安全的一个好规则是“您永远不会太谨慎。如果您自己制作了它,请再次检查。如果其他人制作了它,请假设它是危险的,直到证明是安全的。”
除了安全问题之外,您还应该注意知识产权问题。大多数内容都有版权,在线下和在线上,即使是您可能不期望的内容(例如,维基共享资源 上的大多数图像)。除非您拥有该内容或所有者已向您提供书面且明确的许可,否则不要在您的网页上显示该内容。侵犯版权的处罚非常严重。同样,您永远不会太谨慎。
如果该内容已获得许可,您必须遵守许可条款。例如,MDN 上的内容是根据 CC-BY-SA 许可的。这意味着,即使您进行了重大更改,您也必须正确地引用我们,当您引用我们的内容时。
使用 HTTPS
HTTPS 是HTTP 的加密版本。您应该尽可能地使用 HTTPS 提供您的网站。
- HTTPS 降低了远程内容在传输过程中被篡改的可能性。
- HTTPS 可防止嵌入式内容访问父文档中的内容,反之亦然。
要使您的网站启用 HTTPS,需要安装特殊的安全证书。许多托管提供商提供启用 HTTPS 的托管,而无需您自己进行任何设置来安装证书。但是,如果您确实需要自己为您的网站设置 HTTPS 支持,Let's Encrypt 提供了用于自动创建和安装必要证书的工具和说明——它内置支持最广泛使用的 Web 服务器,包括 Apache Web 服务器、Nginx 等。Let's Encrypt 工具旨在尽可能简化流程,因此没有理由避免使用它或其他可用的方法来使您的网站启用 HTTPS。
注意:GitHub Pages 允许默认情况下通过 HTTPS 提供内容。如果您使用其他托管提供商,您应该检查他们提供哪些支持,以便使用 HTTPS 提供内容。
始终使用sandbox
属性
您希望尽可能地减少攻击者在您的网站上做坏事的权力,因此您应该只给嵌入式内容完成其工作所需的权限。当然,这也适用于您自己的内容。一个用于代码的容器,它可以在其中适当地使用——或用于测试——但不会对其余代码库造成任何伤害(无论是意外的还是恶意的)被称为沙箱。
未进行沙箱处理的内容可能能够执行 JavaScript、提交表单、触发弹出窗口等。默认情况下,您应该通过在没有参数的情况下使用sandbox
属性来强制执行所有可用的限制,如我们之前的示例所示。
如果绝对需要,您可以逐个添加回权限(在sandbox=""
属性值中)——请参阅sandbox
参考条目以获取所有可用的选项。请注意,您永远不应该在sandbox
属性中同时添加allow-scripts
和allow-same-origin
——在这种情况下,嵌入式内容可以绕过同源策略,该策略阻止网站执行脚本,并使用 JavaScript 完全关闭沙箱功能。
注意:如果攻击者能够欺骗人们直接访问恶意内容(在iframe
之外),则沙箱不会提供任何保护。如果存在某些内容可能存在恶意的可能性(例如用户生成的内容),请从与您的主站点不同的域中提供这些内容。
配置 CSP 指令
CSP 代表内容安全策略,并提供一组 HTTP 标头(在从 Web 服务器提供您的网页时与您的网页一起发送的元数据),旨在提高 HTML 文档的安全。在保护<iframe>
方面,您可以配置您的服务器以发送适当的X-Frame-Options
标头。 这可以防止其他网站将您的内容嵌入他们的网页中(这将使点击劫持和其他攻击成为可能),这正是 MDN 开发人员所做的,正如我们之前所看到的。
注意:您可以阅读 Frederik Braun 的文章关于 X-Frame-Options 安全标头,以了解有关此主题的更多背景信息。显然,在本文中对其进行完整解释超出了范围。
<embed> 和 <object> 元素
<embed>
和 <object>
元素的功能与<iframe>
不同——这些元素是用于嵌入外部内容的通用嵌入工具,例如 PDF。
但是,您不太可能经常使用这些元素。如果您需要显示 PDF,通常最好链接到它们,而不是将它们嵌入页面中。
从历史上看,这些元素还被用于嵌入由浏览器插件(如Adobe Flash)处理的内容,但这种技术现在已经过时,不受现代浏览器支持。
如果您发现自己需要嵌入插件内容,则至少需要以下信息
<embed> |
<object> |
|
---|---|---|
URL of the embedded content | src |
data |
准确媒体类型 of the embedded content | type |
type |
height and width (in CSS pixels) of the box controlled by the plugin | height width |
height width |
names and values, to feed the plugin as parameters | ad hoc attributes with those names and values | single-tag <param> elements, contained within <object> |
independent HTML content as fallback for an unavailable resource | not supported (<noembed> is obsolete) |
contained within <object> , after <param> elements |
让我们看一个将 PDF 嵌入页面的<object>
示例(请参阅实时示例 和源代码)。
<object data="mypdf.pdf" type="application/pdf" width="800" height="1200">
<p>
You don't have a PDF plugin, but you can
<a href="mypdf.pdf">download the PDF file. </a>
</p>
</object>
PDF 是纸张和数字之间必要的垫脚石,但它们提出了许多可访问性挑战,并且很难在小屏幕上阅读。它们在某些圈子里仍然很受欢迎,但最好链接到它们,以便用户可以下载或在单独的页面上阅读,而不是将它们嵌入网页中。
测试您的技能!
您已经阅读了本文的结尾,但您还记得最重要的信息吗?您可以在继续学习之前找到一些进一步的测试来验证您是否保留了这些信息——请参阅测试您的技能:多媒体和嵌入。
总结
在网页文档中嵌入其他内容的主题可能会很快变得非常复杂,因此在本文中,我们尝试以一种简单、熟悉的方式来介绍它,这种方式将立即显得相关,同时仍会暗示所涉及技术的一些更高级的功能。首先,您不太可能将嵌入用于超出将地图和视频等第三方内容包含在您的页面中的更多用途。但是,随着您变得更加经验丰富,您可能会开始找到更多使用它们的方法。
除了我们这里讨论的之外,还有许多其他涉及嵌入外部内容的技术。我们在之前的文章中看到了一些,例如<video>
、<audio>
和<img>
,但还有其他需要发现的技术,例如<canvas>
用于 JavaScript 生成的 2D 和 3D 图形,以及<svg>
用于嵌入矢量图形。我们将在模块的下一篇文章中介绍SVG。