Chrome 92 破壞性功能,我這彈窗有何用?
本文轉(zhuǎn)載自微信公眾號「秋風的筆記」,作者藍色的秋風。轉(zhuǎn)載本文請聯(lián)系秋風的筆記公眾號。
近期,Chrome 92 進行了發(fā)布,我們來看看 Chrome 92 中提及的一個影響比較大的破壞性改動。
https://www.chromestatus.com/feature/5148698084376576
對于來自跨域的 iframes 將被禁止 alert、confirm 和 prompt 等功能。
首先我們先來看看 Chrome 對這個破壞性的動機的官方解釋:
如果不明白跨域的可以看我這篇文章:10 種跨域解決方案(附終極方案)
"
現(xiàn)階段來源于 iframe(不管是否跨域的) 的 JS 彈窗(alert/confirm/prompt)是令人困惑,因為它出現(xiàn)的時候看起來像瀏覽器自己的彈窗。這容器欺騙用戶(尤其是 window.prompt),例如 iframe 站點假裝特定消息來自 Chrome(例如 1,2,3)。通過在消息前加上 "say..." 來掩飾這些欺騙行為。然而,當這些 alerts 來自跨域 iframe 時,UI 會更加混亂,因為 Chrome 試圖解釋對話框不是來自瀏覽器本身或頂級頁面。一方面由于跨域 iframe JS 對話框的使用率較低,從事實來看,站點的主要功能通常不需要使用 JS 對話框時,另一方面難以可靠地解釋對話框的來源,因此我們建議刪除跨域 iframe 中的 JS 對話框 。這也將避免我們將通過刪除主機名提示,或者將對話框移動到內(nèi)容區(qū)域的中心,來使對話框更明顯地成為頁面的一部分來明確對話框的含義(這個對話框不是由瀏覽器發(fā)出的)。因此當出現(xiàn)跨域iframe 彈窗(alert/confirm/prompt)將會被阻止,否則這些子 iframes 可能會假裝父頁面的對話框。
為了實際的演示,我們先來看看舊版瀏覽器的效果。
有些運營商或者插件劫持你的頁面或者廣告,會往你的頁面插入一些 iframe 之類的元素。以 alert為例:
- // localhost:5000
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta http-equiv="X-UA-Compatible" content="IE=edge">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>Document</title>
- </head>
- <body>
- <script>
- alert("百度提醒:恭喜中獎!")
- </script>
- </body>
- </html>
我們來模擬一下這個過程:
這個影響可能沒那么嚴重,但是會使用當我們使用window.confirm/window.prompt 來插入到頁面的時候,可就麻煩大了,因為他們是可交換的。
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta http-equiv="X-UA-Compatible" content="IE=edge">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>Document</title>
- </head>
- <body>
- <script>
- const sign = prompt("百度提醒:用戶信息即將過期請確認你的密碼");
- console.log(sign);
- </script>
- </body>
- </html>
也許以上兩個例子比較簡單,絕大多數(shù)人都不會上當,但是如果換成一個域名非常相似,手段更加高明的子網(wǎng)頁,那么其中的安全隱患可想而知。
因為當我們升級了 Chrome 92 之后,這個問題便得以迎刃而解了。
可以看到,當往主站中插入一個 iframe ,里面是有彈窗的,但是主站根本不會理會這個彈窗。
因此當存在跨域的子 iframe ,它的 alert/confirm/prompt 將會失效。這個改動帶來安全性的同時也帶來了很多老系統(tǒng)的兼容性問題。
例如內(nèi)部的 OA 系統(tǒng),就是嵌套一些開放性的頁面提供給第三方調(diào)用,頁面交互就是以 prompt/confirm 進行確認的,那么工程師就要進行相應(yīng)的改動了。
- <form>
- <input type="text" name="name" placeholder="工單內(nèi)容">
- <button id="btn">提交工單</button>
- </form>
- <script>
- btn.onclick = () => {
- const msg = "您真的確定要提交嗎?\n\n請確認!";
- if (confirm(msg) == true) {
- axios.post('xxxx')
- return true;
- } else {
- return false;
- }
- }
- </script>
安全是一把雙刃劍,有些時候更安全了,就會變得麻煩。
例如跨域請求問題,幾乎曾讓每個前端工程師都抓狂過,也許還會抱怨為什么還有跨域這種東西來影響我們的開發(fā)的?
再比如,類似于現(xiàn)在的安全驗證,除了輸入密碼,還得設(shè)置各種密保,或者綁定郵箱啊手機啊類似的種種,都是屬于安全范疇,雖然對用戶來說產(chǎn)品的鏈路變得更加長了,但是它更安全了。