在平時的開發中,或多或少會用到iframe,大部分時候咱們只須要簡單的使用iframe標籤,設置個寬高便可,不多回去深究iframe的別的特性。好比這種用法:html
<iframe src='https://blog.5udou.cn'>
複製代碼
但直到產品經理要求說,iframe嵌入的頁面可不可讓主頁面的url地址發生變化呀?好吧,一會兒懵圈了,我得去查查資料,因而索性就深究深究iframe的一些特性,省得再次尷尬。git
下面全部代碼均可以在這裏找到:github.com/linxiaowu66…github
iframe的特性都是依賴參數配置實現的,現整理以下有用的屬性:web
屬性 | 解釋 | 備註 |
---|---|---|
allow | 能夠爲iframe指定特性策略 | |
allowfullscreen | 是否容許iframe調用requestFullscreen()方法激活全屏模式,這個屬性等同於allow屬性的這個配置:allow="fullscreen" |
|
allowpaymentrequest | 是否容許一個跨域的iframe調用支付請求API | |
csp | 內嵌的資源強制實行同源策略 | |
height | iframe的高度,默認150px | |
importance | 標識在iframe屬性src指示的資源的下載優先級,有auto /high /low 三個等級 |
|
name | 內嵌的瀏覽內容的目標名稱 | |
referrerpolicy | 指示當獲取frame的資源的時候攜帶的referrer,默認是no-referrer-when-downgrade ,也就是僅當發生協議降級(如 HTTPS 頁面引入 HTTP 資源,從 HTTPS 頁面跳到 HTTP 等)時不發送 Referrer 信息。這個規則是如今大部分瀏覽器默認所採用的; |
|
sandbox | 在frame上的內容上運用額外的一下限制,具體哪些字段咱們下面詳細解釋 |
allow屬性的使用須要參考特性策略這一小節。特性策略能夠容許你控制頁面或者iframe可使用哪些特性。頁面控制的話設置在HTTP頭部的Feature-Policy的這個字段,iframe的話就是咱們要說的這個allow字段。跨域
特性策略的書寫規則是:<feature name> <allowlist of origin(s)>
數組
完整的特性名稱參考: Policy Controlled Features或者Feature-Policy 瀏覽器
而allowlist則有以下規則:安全
*
:表示該特性在該文檔下都是容許的,包括全部的嵌套的瀏覽內容(iframes),而不用管這些內容的源。self
:表示該特性在該文檔下都是容許的,而且僅在同源的狀況下嵌套的瀏覽內容(iframes)纔可使用。src
:(iframes的allow屬性專用)表示該特性在這個iframe下容許使用,只要加載的文檔來源的源和iframe的src
屬性指定的URL是同源的。none
:表示該特性在頂層以及嵌套的瀏覽內容下都是被禁用的<origin(s)>
:表示該特性只在一些指定的源下才容許使用,多個源使用空格隔開今天咱們主要講一下iframe下的allow屬性,好比你不容許iframe的頁面全屏、不容許調用攝像頭之類的行爲,能夠這麼配置:bash
<iframe allow="camera 'none'; fullscreen 'none'">
app
好比只容許同源的纔可使用全屏這個特性:
<iframe src="https://example.com..." allow="fullscreen 'src'"></iframe>
好比只容許指定源纔可使用定位功能:
<iframe src="https://google-developers.appspot.com/demos/..." allow="geolocation https://google-developers.appspot.com"></iframe>
這個屬性牽扯到了HTTP的referer策略,咱們知道referer的策略是這樣的:
好比咱們這樣配置:
<iframe allow="fullscreen 'none'" referrerpolicy="no-referrer" src='http://127.0.0.1:3000/iframe.html'></iframe>
複製代碼
咱們經過抓包能夠看到對應的請求是這樣的:
iframe的沙箱模式能夠提供一些額外的配置,當你把一個iframe置爲沙箱的時候,意味着沙箱內的內容的行爲全憑你控制了。
好比你在iframe下這樣配置:
<iframe sandbox="" src='http://127.0.0.1:3000/iframe1.html'></iframe>
可是iframe1.html中卻有對應的js腳本,那麼在控制檯下能夠看到這樣的報錯:
Blocked script execution in 'http://127.0.0.1:3000/iframe1.html' because the document's frame is sandboxed and the 'allow-scripts' permission is not set. 複製代碼
因此當你的iframe有腳本的時候,基本上都會配置allow-scripts
這個屬性。
再好比你的頁面會有form標籤提交數據的時候,若是沒有allow-forms
,則會報這種錯誤:
Blocked form submission to '' because the form's frame is sandboxed and the 'allow-forms' permission is not set. 複製代碼
接下來解釋一下各個配置的含義:
屬性 | 解釋 |
---|---|
allow-forms | 容許資源提交表單 |
allow-modals | 容許資源打開模態窗口,好比window.alert()、window.confirm()、window.print()、window.prompt() |
allow-orientation-lock | 容許資源鎖住屏幕方向 |
allow-pointer-lock | 容許資源使用Pointer Lock API |
allow-popups | 容許彈出窗口(好比window.open(), target="_blank", 或者showModalDialog()),若是這個關鍵詞沒有的話,彈出窗口將會靜默地打開失敗 |
allow-popups-to-escape-sandbox | 容許沙箱文檔打開新窗口,而這些新窗口不須要繼承沙箱模式。 |
allow-presentation | 容許嵌入者控制是否iframe啓用一個展現會話 |
allow-same-origin | 容許將內容做爲普通來源對待。若是未使用該關鍵字,嵌入的內容將被視爲一個獨立的源。 |
allow-scripts | 容許嵌入的瀏覽上下文運行腳本(但不能建立彈窗) |
allow-top-navigation | 容許嵌入的頁面的上下文能夠導航(加載)內容到頂級的瀏覽上下文環境(browsing context)。若是未使用該關鍵字,這個操做將不可用 |
allow-storage-access-by-user-activation | 容許嵌入的頁面請求經過Storage Access API使用父頁面的存儲能力 |
allow-top-navigation-by-user-activation | 容許嵌入的頁面的上下文能夠導航(加載)內容到頂級的瀏覽上下文環境(browsing context),可是隻能經過用戶手勢主動調用來初始化 |
關於沙箱模式的注意點
allow-scripts
和allow-same-origin
,不然的話將容許嵌入的文檔經過代碼刪除sandbox
屬性。雖然你能夠這麼作,可是這樣的話其安全性還不如不用sandbox。通過上面的解釋,想必知道剛開始的那個問題的答案了吧?
frames屬性是一個相似數組的對象;由於frames其實是window對象的別名,frames屬性又是能夠遍歷的,因此它是一個相似數組的對象: window.frames.length === window.length;
frames屬性的每一項是框架內的窗口,即框架內的window對象;frames屬性的每一項並非iframe的dom節點!!!若須要獲取iframe的dom節點能夠經過如下方法: frames[0].frameElement
若是有一個iframe是處於沙箱模式,而且沒有設置allow-same-origin
,那麼雖然你能夠訪問到window.frames的長度爲2,可是當你獲取window.frames[1].location的時候會有這樣的錯誤:
DOMException: Blocked a frame with origin "http://127.0.0.1:3000" from accessing a cross-origin frame
配置了allow-same-origin
的時候:
沒有配置allow-same-origin
的時候:
window.top: 頂層窗口,即最上層的窗口
window.parent: 父窗口,若是一個窗口沒有父窗口,則它的parent屬性爲自身的引用;
window.self: 當前窗口,即自身的引用;