电商平台需要记录用户离开前的最后浏览商品
在线文档工具要自动保存未提交的草稿
数据分析需捕获页面真实停留时长
但传统技术方案会失败:当页面卸载时,普通网络请求会被浏览器强制取消。下面通过真实案例,解析两种100%可靠的解决方案。
当用户关闭标签页,浏览器触发两个关键事件:
pagehide(页面隐藏)
unload(页面卸载)
此时若用fetch或XMLHttpRequest发送请求:
// 失败案例
window.addEventListener('unload', () => {
fetch('/save-data') // 请求将被浏览器中断
});
根本原因:页面JS执行环境已被销毁,浏览器会主动终止未完成的请求。
早期开发者使用同步XMLHttpRequest:
// 已淘汰的方案!
const xhr = new XMLHttpRequest();
xhr.open('POST', '/save', false); // 第三个参数false表示同步
xhr.send(data);
致命缺陷:
完全阻塞主线程,导致页面卡死
用户无法切换标签页,甚至无法关闭浏览器
移动端可能触发系统警告
据统计,同步请求会使页面响应延迟300ms以上,用户体验极差。
这是浏览器专为"最后一刻"数据发送设计的api。
核心优势:
不阻塞页面关闭
浏览器保证请求发送
使用简单
代码示例:
window.addEventListener('pagehide', (event) => {
// 检查是否进入bfcache(页面未真正关闭)
if (event.persisted) return;
const logData = {
duration: performance.now(),
page: location.href
};
// 转换成Blob格式
const blob = new Blob(
[JSON.stringify(logData)],
{ type: 'application/json' }
);
// 发送请求(无需等待响应)
navigator.sendBeacon('/log', blob);
});
注意事项:
特性 | 限制说明 |
---|---|
请求方法 | 仅支持POST |
请求头 | 不可自定义 |
数据大小 | 部分浏览器限制在64KB以内 |
响应处理 | 无法获取服务器返回结果 |
适合需要更多控制的场景:
window.addEventListener('pagehide', async (event) => {
if (event.persisted) return;
const draft = editor.getValue(); // 获取编辑器内容
// 使用keepalive模式
fetch('/api/save-draft', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ content: draft }),
keepalive: true // 关键参数!
});
});
与sendBeacon对比:
能力 | sendBeacon | fetch+keepalive |
---|---|---|
支持GET请求 | ❌ | ✅ |
自定义Header | ❌ | ✅ |
发送FormData | ✅ | ✅ |
跨域凭证携带 | ❌ | ✅ |
根据业务需求决策:
选 sendBeacon:
只需发送简单日志(如点击追踪/页面停留统计)
选 fetch+keepalive:
需要保存用户数据(如文档草稿)、必须携带认证信息、需使用PUT/DELETE方法
事件监听优先用 pagehide
unload 事件可能阻止浏览器使用往返缓存(bfcache),影响用户体验
重要数据需要双重保障
// 提前在visibilitychange事件中发送
document.addEventListener('visibilitychange', () => {
if (document.visibilityState === 'hidden') {
navigator.sendBeacon('/backup-data');
}
});
服务器端必须幂等处理
因网络波动可能造成重复发送,服务端应做去重处理
场景1:需要发送超大数据
拆分数据 + 多次发送:
// 分段发送日志
const chunks = splitLargeData(data);
chunks.forEach(chunk => {
navigator.sendBeacon('/log-chunk', chunk);
});
场景2:低版本浏览器兼容
if (!navigator.sendBeacon) {
// 回退方案:使用同步XHR(仅作保底)
const xhr = new XMLHttpRequest();
xhr.open('POST', url, false);
xhr.send(data);
}
通过sendBeacon和fetch+keepalive,开发者能在不影响用户体验的前提下,实现关闭页面的数据可靠上报。关键点在于:
优先选用浏览器原生方案
根据数据类型选择合适API
服务端做好数据幂等处理
最新统计显示,全球98%的浏览器已支持这两种方案,可放心用于生产环境。
实际部署前,建议使用Chrome DevTools的Application > Background services模块测试请求发送状态,确保万无一失。
本文内容仅供个人学习/研究/参考使用,不构成任何决策建议或专业指导。分享/转载时请标明原文来源,同时请勿将内容用于商业售卖、虚假宣传等非学习用途哦~感谢您的理解与支持!
强制把http请求跳转到https,结果发现App有部分的功能不能使用,因为App一共设置了4种请求方式,分别是GET,POST,DELETE和OPTIONS方式,设置301跳转后所有的请求方法都变成了GET方式,导致一些功能无法正常使用.
几乎所以有关Nginx书只要是讲深入点的就会讲到Nginx请求的11个处理阶段,要记住这些真是不易,人脑特别不擅长记住各种东西,只能做些索引罢了,能做到知道这个知识点在哪儿能找到不就行了,可是你去面试还是问这些理论,所以这里汇总下记录如下
HTTP通信机制是在一次完整的HTTP通信过程中,Web浏览器与Web服务器之间将完成下列7个步骤:建立TCP连接、Web浏览器向Web服务器发送请求命令、Web浏览器发送请求头信息、 Web服务器应答
http请求中的8种请求方法:opions 返回服务器针对特定资源所支持的HTML请求方法 ,Get 向特定资源发出请求,Post 向指定资源提交数据进行处理请求
通过node提供的http模块,可以通过其提供的get()和request()两个方法发起http请求,get()是对request()方法的封装,方便发起get请求,如果要实现post请求,那么需要对request()方法进行封装。
遇到这样一种情况,打开网页两个窗口a,b(都是已经登录授权的),在a页面中退出登录,然后在b页面执行增删改查,这个时候因为授权原因,b页面后端的请求肯定出现异常(对这个异常的处理,进行内部跳转处理),b页面中的ajax请求的回调中就会出现问题
本文所讲的 POST 请求是 HTTP/1.1 协议中规定的众多 HTTP 请求方法的其中最常用的一个。一般使用 POST 请求方法向服务器发送数据(主要是一些创建更新操作),本文讨论的是 POST 请求方法常用的四种数据提交格式。
flutter一直很火的网络请求插件dio,直接上代码,写成一个类,可以直接使用,包含请求的封装,拦截器的封装
当我们在web浏览器的地址栏中输入: www.baidu.com,然后回车,到底发生了什么?DNS域名解析采用的是递归查询的方式,过程是,先去找DNS缓存->缓存找不到就去找根域名服务器->根域名又会去找下一级
nginx首先决定要用配置文件里的哪个server{}块来处理,假设有下面的server{}配置;nginx会根据过来的http请求头里的Host字段里的值,来判断使用哪个server{}。
内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!