当前位置:网站首页>页面关闭前,如何发送一个可靠请求
页面关闭前,如何发送一个可靠请求
2022-07-04 22:17:00 【swlws9527】

一、问题
从 A 页面进入到 B 页面前,向后台发送一个/log请求,如何保证这个请求一定会被接收并处理。
场景复现
function nextPage() {
fetch("/log", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
some: "data",
}),
});
window.location.href = "/other.html";
}
这段代码里,页面切换成功后,后台是接收不到/log请求的。原因:
- js 的执行可以认为分为
主线程、异步线程 - 当页面进入
terminated状态时,会释放所有的资源。也就是说,此时异步线程中未执行的上下文,不会再被处理。
二、解决方案
2.1 async/await
既然是因为异步导致的请求被执行,那改为同步即可。
async function nextPage() {
await fetch("/log", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
some: "data",
}),
});
window.location.href = "/other.html";
}
这种方式会阻塞代码执行
2.2 keepAlive
fetch中设置keepalive为true时,即使发起请求的页面处于terminated状态,也会保持连接。利用这哥特性,可以发送可靠的请求。
function nextPage() {
fetch("/log", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
some: "data",
}),
keepalive: true,
});
window.location.href = "/other.html";
}
2.3 navigator.sendBeacon
使用 sendBeacon() 方法会使用户代理在有机会时异步地向服务器发送数据,同时不会延迟页面的卸载或影响下一导航的载入性能,这意味着:
- 数据发送是可靠的。
- 数据异步传输。
- 不影响下一导航的载入。
代码示例:
function nextPage() {
navigator.sendBeacon(
"/log",
JSON.stringify({
some: "data",
})
);
window.location.href = "/other.html";
}
sendBeacon()API 不支持添加请求头,可以利用Blob做一些改动支持请求头
function nextPage() {
const blob = new Blob([JSON.stringify({
some: "data" })], {
type: "application/json; charset=UTF-8",
});
navigator.sendBeacon("/log", blob);
window.location.href = "/other.html";
}
需要注意的是,在Chrome的network面板下,它的文档类型为ping,不是常见的fetch、xhr类型。
2.4 <a>标签的 ping 属性
越来越多的厂商支持ping属性了。示例:
<a href="/other.html" ping="/log">other page</a>
点击a标签时,会额外发送一个请求/log,它的请求头中包含几个特殊的值:
{
"ping-from": "http://127.0.0.1:3000/",
"ping-to": "http://127.0.0.1:3000/other.html",
"content-type": "text/ping"
}
三、方案选择
如果出现以下情况,可以使用 fetch()+keepalive:
- 需要自定义请求头。
- 使用 GET 请求,不是 POST 请求。
- 支持较旧的浏览器(如 IE),并且已经加载了 fetch polyfill。
但如果满足以下条件,sendBeacon()可能是更好的选择:
- 进行简单的服务请求,不需要太多定制化。
- 更喜欢更干净、更优雅的 API。
- 希望保证您的请求不会与应用程序中发送的其他高优先级请求竞争。
参考:
边栏推荐
- Tla+ introductory tutorial (1): introduction to formal methods
- Solana链上应用Crema因黑客攻击停运
- Common open source codeless testing tools
- ApacheCN 翻译、校对、笔记整理活动进度公告 2022.7
- Mysql root 账号如何重置密码
- LOGO特訓營 第三節 首字母創意手法
- 业务太忙,真的是没时间搞自动化理由吗?
- Li Kou 98: verify binary search tree
- Business is too busy. Is there really no reason to have time for automation?
- 传智教育|如何转行互联网高薪岗位之一的软件测试?(附软件测试学习路线图)
猜你喜欢

质量体系建设之路的分分合合

Introduction and application of bigfilter global transaction anti duplication component

Ascendex launched Walken (WLKN) - an excellent and leading "walk to earn" game

Energy momentum: how to achieve carbon neutralization in the power industry?

安装人大金仓数据库

Concurrent optimization summary

The Sandbox 和数字好莱坞达成合作,通过人力资源开发加速创作者经济的发展

Logo special training camp section III initial creative techniques

LOGO特训营 第四节 字体设计的重要性

Logo Camp d'entraînement section 3 techniques créatives initiales
随机推荐
达梦数据凭什么被称为国产数据库“第一股”?
PMO: compare the sample efficiency of 25 molecular optimization methods
The proofreading activity of data science on the command line second edition was restarted
力扣3_383. 赎金信
LOGO特訓營 第一節 鑒別Logo與Logo設計思路
Solana chain application crema was shut down due to hacker attacks
Deployment of JVM sandbox repeater
High school physics: linear motion
TLA+ 入门教程(1):形式化方法简介
Huawei Nova 10 series released Huawei application market to build a solid application security firewall
Locust性能测试 —— 环境搭建及使用
HBuilder X 常用的快捷键
华泰证券是国家认可的券商吗?开户安不安全?
Sqlserver encrypts and decrypts data
Ascendex launched Walken (WLKN) - an excellent and leading "walk to earn" game
SPSS installation and activation tutorial (including network disk link)
UML图记忆技巧
How can the advertising system of large factories be upgraded without the presence of large models
LOGO特训营 第四节 字体设计的重要性
Logo special training camp section II collocation relationship between words and graphics