從物件到 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.club.tw/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.club.tw/' in a frame because it set 'X-Frame-Options' to 'deny'.
下面的安全部分將更詳細地介紹為什麼您會看到此錯誤,但首先,讓我們看一下我們的程式碼在做什麼。
該示例包含使用<iframe>所需的必要條件
border: none-
如果使用,則
<iframe>在沒有周圍邊框的情況下顯示。否則,預設情況下,瀏覽器會在周圍顯示<iframe>邊框(這通常是不可取的)。 allowfullscreen-
如果設定,則可以使用全屏 API(有點超出本文的範圍)將
<iframe>置於全屏模式。 srcwidth和height-
這些屬性指定您希望 iframe 的寬度和高度。
sandbox-
此屬性(在比其他
<iframe>功能更現代的瀏覽器中工作,例如 IE 10 及更高版本)請求提高的安全設定;我們將在下一節中詳細介紹。
注意:為了提高速度,最好在主要內容載入完成後使用 JavaScript 設定 iframe 的src屬性。這使您的頁面更快地可用,並減少了您的官方頁面載入時間(一個重要的SEO指標)。
安全問題
上面我們提到了安全問題——現在讓我們更詳細地討論一下。我們不希望您第一次就完全理解所有這些內容;我們只是想讓您瞭解這個問題,並提供一個參考,以便您在獲得更多經驗並開始考慮在您的實驗和工作中使用<iframe>時可以返回檢視。此外,沒有必要害怕而不用<iframe>——您只需要小心。繼續閱讀…
瀏覽器製造商和 Web 開發人員已經從痛苦的經驗中瞭解到,如果有人試圖惡意修改您的網頁或欺騙人們做他們不想做的事情(例如透露敏感資訊,如使用者名稱和密碼),iframe 是網路上惡意人士(通常被稱為駭客,或者更準確地說,破解者)攻擊的常見目標(官方術語:攻擊載體)。因此,規範工程師和瀏覽器開發人員已經開發出各種安全機制,使<iframe>更加安全,並且還有一些最佳實踐需要考慮——我們將在下面介紹其中一些。
注意:點選劫持是一種常見的 iframe 攻擊,駭客將不可見的 iframe 嵌入您的文件(或將您的文件嵌入他們自己的惡意網站)並使用它來捕獲使用者的互動。這是一種常見的誤導使用者或竊取敏感資料的方法。
首先,讓我們舉一個簡單的例子——嘗試將我們上面顯示的先前示例載入到您的瀏覽器中——您可以在 GitHub 上找到它(檢視原始碼)。您可能不會看到您預期的頁面,而是會看到一些類似“我無法開啟此頁面”的訊息,如果您檢視瀏覽器開發者工具中的控制檯,您會看到一條訊息告訴您原因。在 Firefox 中,您將看到類似“在框架中載入“https://mdn.club.tw/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 | heightwidth |
heightwidth |
| 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。