用户在页面离开时发送http请求,如何成功

项目场景:

用户在离开页面时,发送http请求给后端,用来收集用户日志数据进行业务分析


问题描述

在浏览器内多页面发生跳转时,无法保证当前页面进程内的请求能够顺利完成,大多数情况下会被浏览器cancled, 请求不能到达后端服务器。

这些http请求能否成功依赖于下面几点:网络连接速度、应用程序性能、甚至于外部服务器本身的配置,可以尝试用下面代码解决

javascript 复制代码
document.getElementById('link').addEveentListener('click', (e) => {
	e.perventDefault();
	fetch("/log", {
		method: "post",
		headers: {
			"Content-Type": "application/json"
		},
		body: JSON.stringify({
			name: "123"
		})
	})
	window.location = e.target.href;
})

但 fetch 会被加入异步队列,页面跳转时队列中剩余的请求仍会被 cancled。

那我们等待请求完成之后再 location 不就行了吗?

javascript 复制代码
document.getElementById('link').addEveentListener('click', async(e) => {
	e.perventDefault();
	await fetch("/log", {
		method: "post",
		headers: {
			"Content-Type": "application/json"
		},
		body: JSON.stringify({
			name: "123"
		})
	})
	window.location = e.target.href;
})

上述代码貌似可以,但是在移动端300ms延迟都能明显感受,万一接口返回太慢,用户就会觉得网站很卡

解决方案:

好在目前前端浏览器都是现代浏览器, fetch提供了 keeplive 参数来处理这个问题:

javascript 复制代码
document.getElementById('link').addEveentListener('click', (e) => {
	 
	fetch("/log", {
		method: "post",
		headers: {
			"Content-Type": "application/json"
		},
		body: JSON.stringify({
			name: "123"
		}),
		keepalive: true  // 设置保持请求
	})
	 
})

使用keepalive 不需要我们阻止默认行为,也不需要 location 跳转。就可以使这个请求发出去


另外

在axios 中也可以设置 keepalive,具体配置如下

是的,如果您创建自己的 axios 实例,您可以使用 axios 执行此操作。

javascript 复制代码
const instance = axios.create({
  baseURL: 'https://some-domain.com/api/',
  timeout: 1000,
  headers: {'X-Custom-Header': 'foobar'},
  httpAgent: new http.Agent({ keepAlive: true }),
});
相关推荐
大面积秃头16 小时前
Http基础协议和解析
网络·网络协议·http
我也要当昏君17 小时前
6.3 文件传输协议 (答案见原书 P277)
网络
Greedy Alg18 小时前
Socket编程学习记录
网络·websocket·学习
刘逸潇200518 小时前
FastAPI(二)——请求与响应
网络·python·fastapi
软件技术员18 小时前
使用ACME自动签发SSL 证书
服务器·网络协议·ssl
我也要当昏君19 小时前
6.4 电子邮件 (答案见原书 P284)
网络协议
Mongnewer19 小时前
通过虚拟串口和网络UDP进行数据收发的Delphi7, Lazarus, VB6和VisualFreeBasic实践
网络
我也要当昏君19 小时前
6.5 万维网(答案见原书P294)
网络
嶔某20 小时前
网络:传输层协议UDP和TCP
网络·tcp/ip·udp
文火冰糖的硅基工坊20 小时前
[嵌入式系统-154]:各种工业现场总线比较
网络·自动驾驶·硬件架构