Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
用戶離開頁面時可靠地發送 HTTP 請求
當瀏覽器內多頁面發生跳轉時,無法保證當前頁面進程內的請求能夠順利完成,大多數情況下,這些請求會被瀏覽器 cancled,此時請求還未到達后端服務器。這些請求的可靠性可能取決于以下幾點:網絡連接速度、應用程序性能,甚至外部服務本身的配置。
因此,在這時發送數據并不能可靠的傳達給后端,如果我們依賴依賴這些日志來做對業務數據進行分析,可能會丟失一些數據。
可以嘗試用代碼解決上述問題:
document.getElementById('link').addEventListener('click', (e) => {
e.preventDefault();
fetch("/log", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
name: 'FedJavaScript'
}),
});
window.location = e.target.href;
});
但 fetch 會被加入異步隊列,頁面跳轉時隊列中剩余的請求仍會被 cancled。
那我們等待請求完成之后再 location 不就行了嗎?
document.getElementById('link').addEventListener('click', async (e) => {
e.preventDefault();
await fetch("/log", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
name: 'FedJavaScript'
}),
});
window.location = e.target.href;
});
可以是可以,但移動端 300ms 但延遲都能有明顯感受,萬一 "/log" 接口返回太慢,用戶就會感覺網站很卡。
好在目前前端都是現代瀏覽器,fetch 提供了 keepalive 參數來處理這個問題:
document.getElementById('link').addEventListener('click', (e) => {
fetch("/log", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
name: 'FedJavaScript'
}),
keepalive: true
});
});
不需要我們阻止默認行為,也不需要 location 跳轉。
個判斷頁面是否真的關閉和刷新的方法
入我的主頁,查看更多JS的分享!
我的代碼有多短,本篇內容就有多短!
本地存儲對比:
今天不想多說話,直接貼上代碼:
//判斷是否支持 比如瀏覽器開啟了隱私模式
var isCookie = () = >{
return navigator.cookieEnabled;
};
//存儲
function setCookie(cname, cvalue, exdays = 0) {
cvalue = encodeURIComponent(JSON.stringify(cvalue));
if (exdays > 0) {
var d = new Date().getTime() + exdays * 24 * 3600 * 1000 + 8 * 3600 * 1000;
var expires = "expires=" + new Date(d).toUTCString();
document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
} else {
document.cookie = cname + "=" + cvalue + ";" + ";path=/";
}
}
//獲取
function getCookie(cname) {
var name = cname + "=";
var ca = document.cookie.split(";");
for (var i = 0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0) == " ") {
c = c.substring(1);
}
if (c.indexOf(name) == 0) {
let d = c.substring(name.length, c.length);
return JSON.parse(decodeURIComponent(d));
}
}
return "";
}
//獲取 通過正則
// function getCookie(name) {
// var arr,
// reg = new RegExp("(^| )" + name + "=([^;]*)(;|$)");
// if ((arr = document.cookie.match(reg))) {
// return JSON.parse(decodeURIComponent(arr[2]));
// } else {
// return null;
// }
// }
//刪除
function deleteCookie(name) {
var date = new Date();
date.setTime(date.getTime() - 1);
var delValue = getCookie(name);
if (delValue) {
document.cookie = name + "=" + delValue + ";expires=" + date.toGMTString();
}
}
使用示例:
//定義key
const tk = "tk2020";
const uk = "uk2020";
//保存
setCookie(tk, "14332239527007001", 0);
setCookie(uk, { id: 1, name: "以氣御碼" }, 0);
//獲取
let token = getCookie(tk);
let user = getCookie(uk);
console.log(token);
console.log(user);
當使用setCookie時,傳0或不傳,表示關閉瀏覽器后就被清除,截圖預覽:
當登錄的信息存儲為這種形式,可以實現關閉瀏覽器,就清除登錄信息。也可以再配合登錄有效期,總不能“只要不關瀏覽器,就不退出登錄了”。
文檔:
有補充請在評論區留言。
*請認真填寫需求信息,我們會在24小時內與您取得聯系。