当前位置:网站首页>页面关闭前,如何发送一个可靠请求
页面关闭前,如何发送一个可靠请求
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。
- 希望保证您的请求不会与应用程序中发送的其他高优先级请求竞争。
参考:
边栏推荐
- Logo special training camp section III initial creative techniques
- More than 30 institutions jointly launched the digital collection industry initiative. How will it move forward in the future?
- Test will: bug classification and promotion solution
- Business is too busy. Is there really no reason to have time for automation?
- [the 2023 autumn recruitment of MIHA tour] open [the only exclusive internal push code of school recruitment eytuc]
- LOGO特训营 第一节 鉴别Logo与Logo设计思路
- Service online governance
- Éducation à la transmission du savoir | Comment passer à un test logiciel pour l'un des postes les mieux rémunérés sur Internet? (joindre la Feuille de route pour l'apprentissage des tests logiciels)
- Unity-VScode-Emmylua配置报错解决
- odps 中 对表进行了一次备份,为什么在元数据库查m_table 时,两张表的逻辑大小不一致,但数
猜你喜欢
2022-07-04:以下go语言代码输出什么?A:true;B:false;C:编译错误。 package main import “fmt“ func main() { fmt.Pri
Redis sentinel simply looks at the trade-offs between distributed high availability and consistency
LOGO特訓營 第一節 鑒別Logo與Logo設計思路
Embedded development: skills and tricks -- seven skills to improve the quality of embedded software code
[acwing] solution of the 58th weekly match
业务太忙,真的是没时间搞自动化理由吗?
The sandbox has reached a cooperation with digital Hollywood to accelerate the economic development of creators through human resource development
Naacl-22 | introduce the setting of migration learning on the prompt based text generation task
虚拟人产业面临的挑战
Locust performance test - environment construction and use
随机推荐
[cooking record] - stir fried 1000 pieces of green pepper
业务太忙,真的是没时间搞自动化理由吗?
Google Earth Engine(GEE)——Tasks升级,实现RUN ALL可以一键下载任务类型中的所有影像
如何实现轻松管理1500万员工?
MySQL storage data encryption
PHP short video source code, thumb animation will float when you like it
PostgreSQL server programming aggregation and grouping
《命令行上的数据科学第二版》校对活动重新启动
PostgreSQL JOIN实践及原理
都说软件测试很简单有手就行,但为何仍有这么多劝退的?
LOGO特训营 第一节 鉴别Logo与Logo设计思路
力扣_回文数
2022-07-04: what is the output of the following go language code? A:true; B:false; C: Compilation error. package main import “fmt“ func main() { fmt.Pri
POM in idea XML dependency cannot be imported
Logo special training camp section 1 Identification logo and logo design ideas
PostgreSQL服务端编程聚合和分组
A large number of virtual anchors in station B were collectively forced to refund: revenue evaporated, but they still owe station B; Jobs was posthumously awarded the U.S. presidential medal of freedo
Challenges faced by virtual human industry
LOGO特訓營 第一節 鑒別Logo與Logo設計思路
sqlserver对数据进行加密、解密