比如有需求是要让页面关闭时, 在数据库中记录用户的一些数据或log日志. 这时就需要在用户关闭页面时发起HTTP请求.
做法是对window.onunload设置事件监听函数, 在函数内发起AJAX请求.
不过有时候页面已经卸载了, 但请求还没有发出, 这时就失败了, 解决这一问题的思路有两种:
1. 在监听函数内做一些比较耗时的操作, 保证请求发出;
2. 使用Navigator.sendBeacon().
方法一: 耗时法.
function log() { let xhr = new XMLHttpRequest(); xhr.open('post', '/log', true); xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); xhr.send('foo=bar'); } window.addEventListener('unload', function(event) { log(); // a time-consuming operation for (let i = 1; i < 10000; i++) { for (let m = 1; m < 10000; m++) { continue; } } });
方法二: Navigator.sendBeacon()
window.addEventListener('unload', logData, false); function logData() { navigator.sendBeacon('/log', analyticsData); }
注意:
1. 增加耗时操作或添加setTimeout都是不合理的, 尽管确实能解决问题.
2. Navigator.sendBeacon()会作为浏览器进程任务, 与当前页面脱钩, 这是处理这一需求的专用方法.
3. Navigator.sendBeacon()是一个可跨域的POST请求, 且不能回调.