監聽瀏覽器關閉事件的解決方案

2022-07-16 01:36:12 字數 2496 閱讀 9234

在web專案開發中,關於瀏覽器關閉事件有兩個很常見的問題:為什麼我沒有監聽瀏覽器關閉事件? 我監聽到了這個事件,但寫在事件裡的非同步請求為什麼傳送不成功?

原因分析:這兩個問題無外乎兩個原因:瀏覽器關閉事件未被觸發 和 非同步請求傳送失敗。

原因1:關閉瀏覽器時一定會觸發事件嗎?如果不一定,那什麼條件下才不觸發呢?

與瀏覽器關閉事件相關事件有onunload和onbeforeunload兩個。區別在於onbeforeunload在onunload之前執行,它還可以阻止onunload的執行。因此我們著重關注onbeforeunload事件。簡單科普一下onbeforeunload事件。

當視窗即將被解除安裝(關閉)時,會觸發該事件.此時頁面文件依然可見,且該事件的預設動作可以被取消. 該函式應當返回乙個字串,當返回的字串不為null或者undefined時,彈出確認視窗讓使用者自行選擇是否關閉當前頁面。一些瀏覽器將該事件返回的字串顯示在彈出窗上。

既然「當視窗即將被解除安裝(關閉)時,會觸發該事件「,那也就是說只要我關閉快就一定會觸發該事件嘍?然而當關閉瀏覽器時,未必一定會觸發onbeforeunload事件。mdn上關於這個事件的觸發條件是這樣描述的。

為避免意外彈出視窗,除非頁面已與之互動,否則瀏覽器可能不會顯示在beforeunload事件中建立的提示,甚至根本不會顯示它們。

那什麼時候算是非與之互動呢?這裡舉個例子,乙個頁面連著重新整理兩次,第二次重新整理時,就認為非與之互動,就不會觸發onbeforeunload事件。,同時對於觸發條件,各個瀏覽器之間也存在差異。具體差異彙總表如下:

說明一下,瀏覽器關閉事件(onbeforeunload)裡已經不可以自定義彈出窗資訊了。mdn中明確寫道:

一些瀏覽器將該事件返回的字串顯示在彈出窗上。但從firefox 4、 chrome 51、opera 38 和safari 9.1開始,通用確認資訊代替事件返回的字串。

原因2:非同步請求傳送失敗了嗎? 

一定失敗。原因傳送非同步請求後,隨即關閉了瀏覽器,這時候這次請求的」三次握手」的」第三次握手」,客戶主機便不會響應伺服器主機,這也就成了乙個失敗的請求。如圖所示。

第三次握手失敗

那麼有什麼解決辦法嗎?

關閉瀏覽器時傳送同步請求,來保證請求傳送完成。但是這樣一來會產生如下問題:

a)      頁面延遲幾秒後再關閉,體驗糟糕。

b)      xmlhttprequest規範中禁止在這個事件處理器中同步呼叫介面。

使用xmlhttprequest傳送同步請求的方式已經計畫從規範中刪除,不再建議開發者使用。

這個時候不熟悉xmlhttprequest的同學也許會問:等一下,我的**裡根本就沒有xmlhttprequest這個物件,所以他的規範憑什麼約束我?

相信你專案裡呼叫介面時已經用到了ajax庫,或者axios庫。其實現有的ajax庫都是對xmlhttprequest物件的一種封裝,而axios是通過promise實現對ajax技術的一種封裝,這樣一來一切都說得通了。原來我們都在直接或者間接的使用著xmlhttprequest物件。

2.fetch 的keepalive屬性

fetch api提供了一套健壯的與伺服器端互動的方式,提供了跨越不同平台 api 的一致介面。它提供了乙個keepalive屬性,保證不管傳送請求的頁面關閉與否,請求都會持續直到結束。不過上傳資料的限制是64 kb。寫法如下:

window.addeventlistener(『onbeforeunload』, );

}

那通過fetch api呼叫的介面如何新增頭資訊呢?以新增token為例,以下**親測有效。

window.addeventlistener(『onbeforeunload』, ,

keepalive:

true

});}

3.sendbeacon()

sendbeacon() 方法可用於通過http將少量資料非同步傳輸到web伺服器。該方法底層的使用的是 fetch api,這樣就能明白為什麼它也有少量資料(64 kb)的上傳資料限制,也能明白為什麼它還能在頁面解除安裝後繼續請求。它的主要優點是簡單,只要用一行**就能搞定。

window.addeventlistener('unload',
總結一下,對於瀏覽器關閉事件,如果我們與頁面未發生互動,那麼當視窗即將被解除安裝(關閉)時便不會觸發onbeforeunload事件;同時一些主流瀏覽器,從某個版本開始,也不允許我們自定義彈窗資訊來給予使用者友好提示了;如果想在該事件中傳送請求,相對於使用xmlhttprequest物件來說,fetch api或者sendbeacon()或是更好的選擇。

close事件 vue vue 監聽瀏覽器關閉事件

用vue做的專案,有個需求就是關閉瀏覽器的時候,需要往後臺提交有個介面,來監聽這個賬號有沒有下線。網上找了很多種方法,一直沒有實現。主要困惑點 1 瀏覽器關閉是事件,是什麼 window.addeventlistener beforeunload e 執行 mounted window.addeve...

關閉瀏覽器的監聽

需求 關閉瀏覽器時,退出,清除session。在網上找了一段 可是測試的時候有偏差,有時關閉瀏覽器可以退出,有時退出不了。分析後發現,當瀏覽器的視窗大小改變後,網頁的寬度沒有及時跟著變,這個專案沒有做到這一點。document.documentelement.scrollwidth 網頁寬度 doc...

瀏覽器快取的解決方案

瀏覽器快取的解決方案 摘要 瀏覽器快取的解決方案,包括傳統前端和現代前端。前言 本文只針對檔案請求 html css js 進行分析,但不涉及json資料請求。1 當瀏覽器向伺服器發起請求,如果請求正常,狀態是200。2 瀏覽器接收到請求結果後,如果會根據響應頭設定的快取規則,把請求結果存起來。3 ...