前幾天工作中遇到一個奇怪的問題,記錄一下。
項目信息:Vue + Element UI 做的後台管理系統。
問題
使用 <a> 鏈接打開新標籤時,頁面跳轉到了登錄頁。
原因
檢查後發現新標籤的 sessionStorage 是空的!由於我把 token 保存在了 sessionStorage 裏面,所以當 sessionStorage 為空時直接跳轉了登錄頁。
但是,為啥是空的??之前還好好的呀,並且,同事電腦打開項目是沒問題的!
兜兜轉轉一下午,把問題鎖定在了 chrome 的版本上,然後就搜索到了下面這一問題:
https://stackoverflow.com/questions/66473527
原來 chrome 89 版本修改了打開新標籤時 sessionStorage 的處理邏輯,這其實涉及到 <a> 標籤的 rel 屬性,我們舉例來説明一下修改前後的區別:
比方説我們從 A 標籤通過 a 鏈接打開了一個新的 B 標籤,
之前瀏覽器的處理邏輯:當 a 標籤的 target="_blank" 時,瀏覽器默認會添加 rel="opener" 屬性,這時 B 標籤的上下文(包含 sessionStorage)是從 A 標籤複製而來的,並且可以通過 window.opener來訪問 A 標籤的 window 對象。沒錯,當 B 標籤不是我們自己的網站時,這時一個極其危險的行為!
現在瀏覽器的處理邏輯:當 a 標籤的 target="_blank" 時,瀏覽器默認會添加 rel="noopener" 屬性,這時 B 標籤的上下文是一個全新的,空白的上下文,並且 B 標籤不可以通過 window.opener 來訪問 A 標籤的 window 對象。很安全!
至此,我們捋清楚了這個問題的前因後果。
解決方案
手動的為 a 鏈接添加一個屬性:
<a href="http://xxx" target="_blank" rel="opener">Link</a>
參考
https://stackoverflow.com/questions/66473527
a 標籤的 target="__blank" 和 window.opener 可以實現惡意跳轉?
Window.opener - MDN
鏈接類型 - MDN
當 target="_blank" 時是否要默認添加 rel="opener" 的討論 - Github