最近在作實時視頻這塊的封裝,須要客戶端Ajax實時上報狀態給服務端,以確認用戶的當前的通話狀態。這個時候,涉及到當用戶離開客戶端時候(關閉瀏覽器),發送離線狀態給服務器。web
瀏覽器關閉事件會有兩個,unload 和 **beforunload,二者是有區別的,從字面上來看,beforunload的調用是在 unload以前。瀏覽器
一、beforeunload在用戶即將離開頁面時觸發,它返回一個字符串,瀏覽器會向用戶展現並詢問這個字符串以肯定是否離開。bash
二、unload在用戶已經離開時觸發,咱們在這個階段僅能夠作一些沒有延遲的操做,因爲種種限制,不多被使用。服務器
三、須要注意的是,若是在兩個事件監聽中添加 alert、confirm、prompt會忽略app
四、生效狀況:異步
window.onunload = function(){
// 相關代碼
}
window.onbeforeunload = function(){
// 相關代碼
}
window.addEventListener('unload', ()=>{
// 相關代碼
});
window.addEventListener('beforeunload', ()=>{
// 相關代碼
});
複製代碼
有時候兩個監聽須要配合使用,固然,避免重複調用,要作一些處理。post
有了上面兩個監聽爲前提下,咱們來關心一下怎麼能把請求發送成功給服務端。若是隻是在監聽中隨便寫個請求,說不定請求還沒發出去,已經被瀏覽器中止了,異步的Ajax不必定能準確的到達服務端。下面有三個想法能夠進行實現。ui
你們第一反應多是,把請求設置爲同步請求,上代碼:url
var xml = new XMLHttpRequest();
xml.open('POST', url , false); // false表示不是異步請求
xml.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xml.onreadystatechange = function() {
if (xml.readyState == 4 && xml.status == 200) {
var responeData = xml.responseText;
var data = JSON.parse(responeData);
} else {
// 處理異常
}
};
xml.send('account=1&password=123456');
複製代碼
這種方法能夠實現,可是對用戶體驗會有比較大的影響,而且在http協議最新的提案中,有考慮剔除請求同步標準spa
相關使用方法
body = JSON.stringify(body);
// 原來是 xhr.send(body)變爲
navigator.sendBeacon(url,body);
複製代碼
支持發送的body能夠是ArrayBufferView, Blob, DOMString, 或者 FormData 類型的數據。 根據MDN的介紹:
主要用於知足 統計和診斷代碼的須要,這些代碼一般嘗試在卸載(unload)文檔以前向web服務器發送數據。過早的發送數據可能致使錯過收集數據的機會。然而, 對於開發者來講保證在文檔卸載期間發送數據一直是一個困難。由於用戶代理一般會忽略在卸載事件處理器中產生的異步 XMLHttpRequest 。
複製代碼
下面介紹一下兩種其餘不一樣類型的發送方式
blob = new Blob([`accoutn=12332323`], {type : 'application/x-www-form-urlencoded'});
navigator.sendBeacon("/leave", blob);
複製代碼
var fd = new FormData();
fd.append('account', 123);
navigator.sendBeacon("/leave", fd);
複製代碼
=-=結束語:經過以上兩種結合,能夠在頁面結束時候,進行Ajax請求的發送=-=
原文參考相關連接:juejin.im/post/5c7e54…