你知道關閉頁面時怎麼向後臺傳送訊息嗎?

語言: CN / TW / HK

需求

這兩天碰到一個需求:在使用者重新整理頁面或者關閉頁面的時候,前端要給後臺發一條請求,釋放該頁面的授權佔用。

分析了一下,這不就是在頁面解除安裝時發請求嘛,三下五除二就實現一版:

window.addEventListener("beforeunload", () => {
let oReq = new XMLHttpRequest();
oReq.open("POST", "http://127.0.0.1:1991/loginout");
oReq.send(JSON.stringify({name: "程式設計三昧"}));

測試發現:

  • 重新整理頁面時基本滿足需求(偶爾也會有後臺接收不到請求的現象,但概率很低)
  • 關閉頁面時,後臺接收不到請求

既然非同步 Ajax 不行,那就試試同步的吧,結果直接報錯了:

搜了一下,解釋如下:

Chrome now disallows synchronous XHR during page dismissal when the page is being navigated away from or closed by the user. This involves the following events (when fired on the path of page dismissal): beforeunload, unload, pagehide, and visibilitychange.

概括起來就是:對現在的 Chrome 來說,在頁面導航離開或者被使用者關閉時,不允許傳送同步 XHR 請求,涉及到的事件有:beforeunload、unload、pagehide 和 visibilitychange。

雖然問題沒解決,但是卻長知識了,這波不太虧!

navigator.sendBeacon()

後來通過搜尋,看到有一個介面是專門來幹這事的,那就是 navigator.sendBeacon()

描述

這個方法主要用於滿足統計和診斷程式碼的需要,這些程式碼通常嘗試在解除安裝(unload)文件之前向web伺服器傳送資料。

語法

navigator.sendBeacon(url, data);

引數

  • url 表明 data 將要被髮送到的網路地址。
  • data 引數是將要傳送的 ArrayBufferViewBlobDOMString 或者 FormData 型別的資料。

返回值

當用戶代理成功把資料加入傳輸佇列時,sendBeacon() 方法將會返回 true,否則返回 false

實現

既然有了介面,那實現起來就簡單了。

程式碼

 window.addEventListener("beforeunload", (e) => {
    const data = {name: "程式設計三昧"};
    window.navigator.sendBeacon("http://127.0.0.1:1991/loginout", JSON.stringify(data));
});

效果

不管是重新整理頁面還是關閉頁面,後臺都能接收到前端傳送過來的請求,完美實現需求。

總結

瀏覽器現在功能越來越強大,支援的 API 也越來越豐富,放在之前很難實現的功能,現在可能就是輕而易舉的事,還是要多關注技術動態。

~

~本文完,感謝閱讀!

~

學習有趣的知識,結識有趣的朋友,塑造有趣的靈魂!

大家好,我是〖程式設計三昧〗的作者 隱逸王,我的公眾號是『程式設計三昧』,歡迎關注,希望大家多多指教!

你來,懷揣期望,我有墨香相迎! 你歸,無論得失,唯以餘韻相贈!

知識與技能並重,內力和外功兼修,理論和實踐兩手都要抓、兩手都要硬!