谷歌瀏覽器新開頁面進程問題


  開發項目過程中,會遇到點擊頁面上某個東西,要在新窗口中打開一個頁面的需求。如果你認為是簡簡單單的打開一個新窗口,那就會掉進谷歌瀏覽器的坑里了。

  場景:A頁面,點擊按鈕,新開窗口跳轉到該項目的B頁面,如果B頁面的請求尚未結束,直接關閉B頁面,此時A頁面會卡死

  原因:谷歌瀏覽器在給新開窗口分配進程時,看是否同源,非同源頁面會單獨分配一個新進程,而同源頁面只會分配一個相同的新進程。在上述場景中,A,B頁面同源,所以谷歌瀏覽器只會分配一個進程,這就導致B頁面在請求未結束時就關閉,A頁面會卡死。

  下面來看一下不同方式打開新頁面的瀏覽器分配進程情況。

一、查看谷歌瀏覽器的進程

  1、找到瀏覽器的自定義及控制圖標

     2、點擊找到更多工具

  3、點擊更多工具並點擊任務管理器

  4、進程如下:

二、使用a標簽打開新窗口

  1、使用a標簽打開非同源窗口

<a href="https://www.baidu.com/" target="_blank">新開窗口跳轉到百度</a>
<a href="https://www.cnblogs.com/" target="_blank">新開窗口跳轉到博客園</a>

  使用a標簽分別打開了百度以及博客園首頁,這兩個非同源,所以瀏覽器會分配兩個新進程。如下圖:

  2、使用a標簽打開同源窗口

<a href="https://juejin.im/" target="_blank">新開窗口掘金</a>
<a href="https://juejin.im/" target="_blank">新開窗口掘金</a>

  使用a標簽打開掘金首頁,這兩個同源,所以瀏覽器只會分配一個新進程。如下圖:

 三、使用window.open打開新窗口

  使用window.open打開新窗口與a標簽打開結果相同

 <Button onClick={() => window.open('https://www.csdn.net/')}>window.open跳轉到CSDN</Button>
 <Button onClick={() => window.open('https://www.csdn.net/')}>window.open跳轉到CSDN(同源)</Button>
 <Button onClick={() => window.open('https://www.jianshu.com/')}>window.open跳轉到簡書(非同源)</Button>

  點擊3個Button,打開3個新窗口,只分配了2個進程CSND同源,共用一個進程,簡書單獨一個進程

 四、如何解決同源同一進程

  一般來說,新開窗口肯定是想新開一個進程,這樣兩邊頁面不會受到影響。要想同源不同進程,就需要將新創建的標簽頁的 opener 屬性設置為 null,表示在單獨的進程中運行新標簽頁,這樣瀏覽器就會給每一個新開窗口分配一個進程

  1、window.open設置opener為null不會起作用

const handleClick = () => {
    let otherWindow: any = window.open();
    otherWindow.opener = null;
    otherWindow.location = 'https://www.baidu.com/';
}
<Button onClick={handleClick}>window.open設置opener跳轉到百度</Button>
<Button onClick={handleClick}>window.open設置opener跳轉到百度</Button>

   將opener設置為null之后,再打開新窗口。結果瀏覽器並沒有單獨分配進程,還是同源分配一個進程。

  

  這就要使用a標簽代替window.open來解決

   2、a標簽添加rel="noopener noreferrer"解決同源同進程

<a href="https://www.baidu.com/" target="_blank" rel="noopener noreferrer">新開窗口添加rel跳轉到百度</a>
<a href="https://www.baidu.com/" target="_blank" rel="noopener noreferrer">新開窗口添加rel跳
轉到百度</a>

  a標簽添加rel="noopener noreferrer"就相當於將新窗口的opener置為null,此時瀏覽器會給新開窗口都單獨分配一個進程

五、項目中使用

  創建a標簽並觸發方法打開新頁面

 let a = document.createElement('a');     //創建a標簽
 a.setAttribute('href', url);               //url即為需要打開的新頁面的url
 a.setAttribute('target', '_blank');           //_blank新窗口打開
 a.setAttribute('rel', 'noopener noreferrer');  //添加rel
 document.body.appendChild(a);    
 a.click();                         //觸發click

   這樣每次打開一個新窗口時,就會創建一個新的進程。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM