到目前爲止,您應該掌握了將圖像、視頻和音頻嵌入到網頁上的訣竅了。此刻,讓我們繼續深入學習,來看一些能讓您在網頁中嵌入各種內容類型的元素: <iframe>, <embed>
和<object>
元素。<iframe>
用於嵌入其他網頁,另外兩個元素則允許您嵌入PDF,SVG
,甚至Flash
— 一種正在被淘汰的技術,但您仍然會時不時的看到它。
嵌入的簡史
很久以前,很流行在網絡上使用框架創建網站 — 網站的一小部分存儲於單獨的HTML
頁面中。這些被嵌入在一個稱爲框架集的主文檔中,它允許您指定每個框架能夠填充在屏幕上的區域,非常像調整表格的列和行的大小。這些做法在90年代中期至90年代後期被認爲是比較酷的,有證據表明,將網頁分解成較小的塊,這樣有利於下載速度 —尤其是在那時網絡連接速度太慢的情況下更爲明顯。然而,這些技術有很多問題,隨着網絡速度越來越快,這些技術帶來的問題遠超過它們帶來的積極因素,所以你再也看不到它們被使用了。
一小段時間之後(20世紀90年代末,21世紀初),插件技術變得非常受歡迎,例如Java Applet
和Flash
— 這些技術允許網絡開發者將豐富的內容嵌入到網頁中,例如視頻和動畫等,這些內容不能通過HTML
單獨實現。嵌入這些技術是通過諸如<object>
和較少使用<embed>
的元素來實現的,當時它們非常有用。由於許多問題,包括可訪問性、安全性、文件大小等,它們已經過時了; 如今,大多數移動設備不再支持這些插件,桌面端也逐漸不再支持。
最後,<iframe>
元素出現了(連同其他嵌入內容的方式,如<canvas>,<video>
等),它提供了一種將整個web頁嵌入到另一個網頁的方法,看起來就像那個web頁是另一個網頁的一個<img>
或其他元素一樣。<iframe>
現在經常被使用。
瞭解完歷史之後,讓我們繼續往下看以瞭解如何使用它們。
自主學習:嵌入類型的使用
在這篇文章中,我們將直接進入自主學習部分,讓你立即體會到嵌入技術的實用性。大家都非常熟悉Youtube
,但很多人不瞭解它所提供的一些分享功能。讓我們來看看Youtube
如何讓我們通過<iframe>
在頁面中嵌入喜歡的視頻。
- 首先,去
Youtube
找一個喜歡的視頻。 - 在視頻下方,您會看到一個共享按鈕 - 點擊查看共享選項。
- 選擇“ 嵌入”選項卡,您將得到一些
<iframe>
代碼 - 複製一下。 - 粘貼到下面的輸入框裏,看看輸出結果是什麼。
此外,您還可以試試在示例中嵌入Google地圖:
- 去
Google
地圖找一個喜歡的地圖。 - 點擊UI左上角的“漢堡菜單”(三條水平線)。
- 選擇共享或嵌入地圖選項。
- 選擇嵌入地圖選項,這將給你一些
<iframe>
代碼 - 複製一下。 - 粘貼到下面的輸入框,看看輸出結果是什麼。
如果你犯了某些錯誤,你可以點擊Reset
按鈕以重置編輯器。如果你確實被卡住了, 按下Show solution
按鈕以借鑑答案。
<iframe src="https://player.bilibili.com/player.html?aid=19390801&cid=31621681&page=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true"> </iframe> <p>改革春風吹滿地</p>
Iframe
詳解
是不是很簡單又有趣呢?<iframe>
元素旨在允許您將其他Web文檔嵌入到當前文檔中。這很適合將第三方內容納入您的網站,您可能無法直接控制,也不希望實現自己的版本 - 例如來自在線視頻提供商的視頻,Disqus等評論系統,在線地圖提供商,廣告橫幅等。您通過本課程使用的實時可編輯示例就是使用<iframe>
實現的。
我們會在後面提到,關於<iframe>
有一些嚴重的安全隱患需要考慮,但這並不意味着你不應該在你的網站上使用它們 — 它只需要一些知識和仔細地思考。讓我們更詳細地探索這些代碼。假設您想在其中一個網頁上加入MDN
詞彙表,您可以嘗試以下方式:
<iframe src="https://developer.mozilla.org/en-US/docs/Glossary"
width="100%" height="500" frameborder="0"
allowfullscreen sandbox>
<p>
<a href="https://developer.mozilla.org/en-US/docs/Glossary">
Fallback link for browsers that don't support iframes
</a>
</p>
</iframe>
此示例包括使用以下所需的<iframe>
基本要素:
allowfullscreen
如果設置,<iframe>
則可以通過全屏API
設置爲全屏模式(稍微超出本文的範圍)。
frameborder
如果設置爲1
,則會告訴瀏覽器在此框架和其他框架之間繪製邊框,這是默認行爲。0
刪除邊框。不推薦這樣設置,因爲在CSS
中可以更好地實現相同的效果。border: none;
src
該屬性與<video>/<img>
一樣包含指向要嵌入文檔的URL
路徑。
width
和 height
這些屬性指定您想要的iframe
的寬度和高度。
備選內容
與<video>
等其他類似元素相同,您可以在<iframe></iframe>
標籤之間包含備選內容,如果瀏覽器不支持<iframe>
,將會顯示備選內容,這種情況下,我們已經添加了一個到該頁面的鏈接。現在您幾乎不可能遇到任何不支持<iframe>
的瀏覽器。
sandbox
該屬性需要在已經支持其他<iframe>
功能(例如IE 10及更高版本)但稍微更現代的瀏覽器上才能工作,該屬性可以提高安全性設置; 我們將在下一節中更加詳細地談到。
注意:爲了提高速度,在主內容完成加載後,使用JavaScript設置iframe
的src
屬性是個好主意。這使您的頁面可以更快地被使用,並減少您的官方頁面加載時間(重要的SEO指標)。
安全隱患
以上我們提到了安全問題 - 現在我們來詳細介紹一下這一點。我們並不期望您第一次就能完全理解所有內容; 我們只想讓您意識到這一問題,在您更有經驗並開始考慮在您的實驗和工作中使用<iframe>
時爲你提供參考。此外,沒有必要害怕和不使用<iframe>
—你只需要謹慎一點。繼續看下去吧…
瀏覽器製造商和Web開發人員瞭解到網絡上的壞人(通常被稱爲黑客,或更準確地說是破解者),如果他們試圖惡意修改您的網頁或欺騙人們進行不想做的事情時常把iframe
作爲共同的攻擊目標(官方術語:攻擊向量),例如顯示用戶名和密碼等敏感信息。因此,規範工程師和瀏覽器開發人員已經開發了各種安全機制,使<iframe>
更加安全,這有些最佳方案值得我們考慮 - 我們將在下面介紹其中的一些。
單擊劫持是一種常見的
iframe
攻擊,黑客將隱藏的iframe嵌入到您的文檔中(或將您的文檔嵌入到他們自己的惡意網站),並使用它來捕獲用戶的交互。這是誤導用戶或竊取敏感數據的常見方式。
一個快速的例子 — 嘗試在瀏覽器中加載上面的例子 - 你也可以在Github
上找到它(參見源代碼)。你將不會看到任何內容,但如果你點擊瀏覽器開發者工具中的控制檯,你會看到一條消息,告訴你爲什麼沒有顯示內容。在Firefox
中,您會被告知:“X-Frame-Options
拒絕加載https://developer.mozilla.org/en-US/docs/Glossary
”。這是因爲構建MDN
的開發人員已經在網站頁面的服務器上設置了一個不允許被嵌入到<iframe>
的設置(請參閱配置CSP
指令)這是有必要的 — 整個MDN
頁面被嵌入在其他頁面中沒有多大意義,除非您想要將其嵌入到您的網站上並將其聲稱爲自己的內容,或嘗試通過單擊劫持來竊取數據,這都是非常糟糕的事情。此外,如果每個人都這樣做,所有額外的帶寬將花費Mozilla
很多資金。
只有在必要時嵌入
有時嵌入第三方內容(例如YouTube
視頻和地圖)是有意義的,但如果您只在完全需要時嵌入第三方內容,您可以省去很多麻煩。網絡安全的一個很好的經驗法則是“你怎麼謹慎都不爲過,如果你決定要做這件事,多檢查一遍;如果是別人做的,在被證明是安全的之前,都假設這是危險的。”
除了安全問題,你還應該意識到知識產權問題。無論在線內容還是離線內容,絕大部分內容都是有版權的,甚至是一些你沒想到有版權的內容(例如,Wikimedia Commons
上的大多數圖片)。不要在網頁上展示一些不屬於你的內容,除非你是所有者或所有者給了你明確的、書面的許可。對於侵犯版權的懲罰是嚴厲的。再說一次,你再小心也不爲過。
如果內容獲得許可,你必須遵守許可條款。例如,MDN
上的內容是在CC-BY-SA
下許可的,這意味着,如果你要引用我們的內容,就必須用適當的方式註明來源,即使你對內容做了實質性的修改。
使用 HTTPS
HTTPS
是HTTP
的加密版本。您應該儘可能使用HTTPS
爲您的網站提供服務:
HTTPS
減少了遠程內容在傳輸過程中被篡改的機會,HTTPS
防止嵌入式內容訪問您的父文檔中的內容,反之亦然。
使用HTTPS
需要一個安全證書,這可能是昂貴的(儘管Let's Encrypt
讓這件事變得更容易),如果你沒有,可以使用HTTP
來爲你的父文檔提供服務。但是,由於HTTPS
的第二個好處,無論成本如何,您絕對不能使用HTTP
嵌入第三方內容(在最好的情況下,您的用戶的Web瀏覽器會給他們一個可怕的警告)。所有有聲望的公司,例如Google Maps或Youtube,當您嵌入內容時,<iframe>
將通過HTTPS
提供 - 查看<iframe>
src
屬性內的URL
。
注意:Github頁面允許默認情況下通過HTTPS提供內容,因此對託管內容很有用。如果您正在使用不同的託管,並且不確定,請向您的託管服務商詢問。
始終使用sandbox
屬性
想儘可能減少攻擊者在你的網站上做壞事的機會,那麼你應該給嵌入的內容僅能完成自己工作的權限。當然,這也適用於你自己的內容。一個允許包含在其裏的代碼以適當的方式執行或者用於測試,但不能對其他代碼庫(意外或惡意)造成任何損害的容器稱爲沙盒。
未沙盒化(Unsandboxed
)內容可以做得太多(執行JavaScript
,提交表單,彈出窗口等)默認情況下,您應該使用沒有參數的sandbox
屬性來強制執行所有可用的限制,如我們前面的示例所示。
如果絕對需要,您可以逐個添加權限(sandbox=""
屬性值內) - 請參閱sandbox
所有可用選項的參考條目。其中重要的一點是,你永遠不應該同時添加allow-scripts
和allow-same-origin
到你的sandbox
屬性中-在這種情況下,嵌入式內容可以繞過阻止站點執行腳本的同源安全策略,並使用JavaScript完全關閉沙盒。
注意:如果攻擊者可以欺騙人們直接訪問惡意內容(在
iframe
之外),則沙盒無法提供保護。如果某些內容可能是惡意的(例如,用戶生成的內容),請保證其是從不同的域向您的主站點提供的。
配置CSP
指令
CSP
代表內容安全策略,它提供一組HTTP
標頭(由web服務器發送時與元數據一起發送的元數據),旨在提高HTML文檔的安全性。在<iframe>
s安全性方面,您可以將服務器配置爲發送適當的X-Frame-Options
標題。這樣做可以防止其他網站在其網頁中嵌入您的內容(這將導致點擊和一系列其他攻擊),正如我們之前看到的那樣,MDN
開發人員已經做了這些工作。
注意:您可以閱讀
Frederik Braun
的帖子在X-Frame-Options
安全性頭上來獲取有關此主題的更多背景信息。顯然,在這篇文章中已經解釋得很清楚了。
<embed>
和<object>
元素
<embed>
和<object>
元素的功能不同於<iframe>
—— 這些元素是用來嵌入多種類型的外部內容的通用嵌入工具,其中包括像Java小程序和Flash,PDF(可在瀏覽器中顯示爲一個PDF插件)這樣的插件技術,甚至像視頻,SVG和圖像的內容!
注意:插件是一種對瀏覽器原生無法讀取的內容提供訪問權限的軟件。
然而,您不太可能使用這些元素 - Applet
幾年來一直沒有被使用;由於許多原因,Flash
不再受歡迎(見下面的插件案例);PDF
更傾向於被鏈接而不是被嵌入;其他內容,如圖像和視頻都有更優秀、更容易元素來處理。插件和這些嵌入方法真的是一種傳統技術,我們提及它們主要是爲了以防您在某些情況下遇到問題,比如內部網或企業項目等。
如果您發現自己需要嵌入插件內容,那麼您至少需要一些這樣的信息:
說明 | <embed> |
<object> |
---|---|---|
嵌入內容的網址 | src | data |
嵌入內容的準確媒體類型 | type | type |
由插件控制的框的高度和寬度(以CSS像素爲單位) | height | height |
width | width | |
名稱和值,將插件作爲參數提供 | 具有這些名稱和值的ad hoc屬性 | 單標籤<param> 元素,包含在內<object> |
獨立的HTML內容作爲不可用資源的回退 | 不支持(<noembed> 已過時) |
包含在元素<object> 之後<param> |
注意:
<object>
需要data
屬性,type
屬性或兩者。如果您同時使用這兩個,您也可以使用該typemustmatch
屬性(僅在Firefox
中實現,在本文中)。typemustmatch
保持嵌入文件不運行,除非type
屬性提供正確的媒體類型。typemustmatch
因此,當您嵌入來自不同來源的內容(可以防止攻擊者通過插件運行任意腳本)時,可以賦予重要的安全優勢。
下面是一個使用該<embed>
元素嵌入Flash影片的示例:
<embed src="whoosh.swf" quality="medium"
bgcolor="#ffffff" width="550" height="400"
name="whoosh" align="middle" allowScriptAccess="sameDomain"
allowFullScreen="false" type="application/x-shockwave-flash"
pluginspage="http://www.macromedia.com/go/getflashplayer">
很可怕,不是嗎 。Adobe Flash
工具生成的HTML
往往更糟糕,使用嵌入<object>
元素的<embed>
元素來覆蓋所有的基礎(查看一個例子)。甚至有一段時間,Flash
被成功地用作HTML5
視頻的備用內容,但是這種情況越來越被認爲是不必要的。
現在來看一個<object>
將PDF
嵌入一個頁面的例子:
<object data="mypdf.pdf" type="application/pdf"
width="800" height="1200" typemustmatch>
<p>You don't have a PDF plugin, but you can <a href="myfile.pdf">download the PDF file.</a></p>
</object>
PDF
是紙與數據之間重要的階梯,但它們在可訪問性上有些問題,並且可能難以在小屏幕上閱讀。它們在一些圈子中仍然受歡迎,我們最好是用鏈接指向它們,而不是將其嵌入到網頁中,以便它們可以在單獨的頁面上被下載或被閱讀。
總結
在Web文檔中嵌入其他內容這一主題可以很快變得非常複雜,因此在本文中,我們嘗試以一種簡單而熟悉的方式來介紹它,這種介紹方式將立即顯示出相關性,同時仍暗示了一些涉及更高級功能的技術。剛開始,除了嵌入第三方內容(如地圖和視頻),您不太可能在網頁上使用到嵌入技術。當你變得更有經驗時,你可能會開始爲他們找到更多的用途。
除了我們在這裏討論的那些外,還有許多涉及嵌入外部內容的技術。我們看到了一些在前面的文章中出現的,如<video>,<audio>
和<img>
,但還有其它的有待關注,如 <canvas>
用於JavaScript生成的2D和3D圖形,<svg>
用於嵌入矢量圖形。我們將在此學習模塊的下一篇文章中學習SVG
。