天天看點

浏覽器失控的後退按鈕?——Chrome的導航安全政策

記錄一個

Chrome

的特性引發的問題。

背景

前些日子有一個同僚找我,說是頁面上出現了非常奇怪的跳轉現象。

簡單來說就是,他做了一個前置

頁面A

,用于擷取使用者登入資訊,根據使用者角色的不同,自動跳轉至不同路由的頁面。但是當他點選浏覽器後退時,傳回的不是

頁面A

,而是空白的新标簽頁。相當于

頁面A

的曆史記錄被浏覽器吃掉了,是以直接後退到了新标簽頁。

我之前遇到過浏覽器導航後退出現了非預期的情況,但隻是出現在UC浏覽器,并且是在 pathname 路由的模式下。但同僚給我發的視訊中,使用的是

Chrome

,且用的 hash 路由。之前的經驗讓我第一時間聯想到,是不是

Chrome

出現新bug了?

測試

我寫了一個簡單的可複現用例

// PageA.tsx
import React, { useEffect } from 'react';
import { history } from 'umi';
const PageA = () => {
  useEffect(() => {
    setTimeout(() => {
      history.push('/sub-page/1');
      // window.history.pushState(null, '', '/sub-page/1');
      // location.href = '/sub-page/1';
    }, 1000);
  }, []);
  return (
    <div>
      This is Page A.
    </div>
  );
};
export default PageA;      

然後我得到了這樣一個穩定的現象,

頁面A

在1秒後跳轉至

頁面B

,但點選後退按鈕時,并不能回退到

頁面A

,且不論是使用

react

禦用的

history

或原生

history

或是直接修改

location

,都能穩定複現這個情況。

浏覽器失控的後退按鈕?——Chrome的導航安全政策

然後我也發現了能夠避免吃掉曆史記錄的方式,就是使用者與頁面産生互動,比如這樣點選一下頁面,前進後退就正常了:

浏覽器失控的後退按鈕?——Chrome的導航安全政策

emmm?“使用者互動後才生效”這個操作怎麼和之前 Chrome 提出的,禁止在使用者與頁面互動前自動播放有聲視訊的安全政策如出一轍?我隐約感覺到這可能不是bug

排查

由于我先入為主的觀點,我還是以為這是

Chrome

的缺陷,也就是我認為,在使用者與頁面互動之前,浏覽器遺漏了曆史記錄,是以我在

chromium

issue

看闆上搜了好一會兒,但是并沒有得到我想要的結果。

我不死心,拉了曆史版本的

Chromium

挨個測試,最後發現在74版本的

Chromium

上,出現了這個特性。這個版本距離現在已經兩年了吧,這麼明顯的問題不可能沒有人提出吧?

于是我開始往浏覽器新特性的方向去查找,查了74版本相關的

New in Chrome

,但似乎沒有找到太多内容。

就在這時,同僚給我發來了一個

連結

,這裡說明了在使用者與頁面互動之前,

Chrome

的前進後退按鈕會忽略該網站所跳轉過的曆史記錄棧。

這個操作是為了防止網站惡意攔截使用者的浏覽器導航而做的。例如該網站通過在

頁面A

進入頁面後立即

push

跳轉到新頁面的代碼,導緻你後退時便觸發該跳轉,而永遠無法後退到更早的頁面。

後來我也找到了相關的

文章

,看來之前的方向不太對。

結語

由于存在這個特性,作為前端工程師的我們,在頁面跳轉時就要盡量避免這種,進入頁面後直接跳轉頁面,且還需要使用者進行後退操作的業務邏輯。

另外時間關系,我隻搜尋到了上面兩個部落客發的介紹文章,如果有官方對于該特性的文檔,歡迎告知。