页面卸载时向后端发送接口

工作中遇到一个需求,需要在用户关闭或者刷新页面时向后端发送该用户的身份信息。

浏览器页面卸载时会触发beforeunload和unload事件,由于unload限制比较多,因此这里选择了beforeunload。

问题:常用的异步ajax请求在unload/beforeunload事件内是不可靠的,浏览器可能会无视异步请求从而导致后端收不到。可以使用下述方法。

1. 同步ajax

window.addEventListener('beforeunload', () => {
    const url = 'test.com';
    const params = { test : 'test' }; 
	$.ajax({
        type: 'POST',
        url: url,
        data: params,
        async: false
    }); 
});

同步ajax会阻断浏览器的unload,直到ajax环节结束后才会继续进行unload。

此方法的缺点是由于页面会在ajax请求结束后才延迟卸载,会导致关闭时浏览器出现卡顿降低用户的体验。

注意:chrome不支持在页面关闭事件内使用同步XMLHttpRequest请求

Disallow sync XHR in page dismissal - Chrome Platform Status

2. beacon

window.addEventListener('beforeunload', () => {
    const url = 'test.com';
    const params = { test : 'test' }; 
	navigator.sendBeacon(url, JSON.stringfy(params));
});

beacon api设计就是用来解决页面卸载时发送请求的问题。他能保证在页面unload完成前请求能够被发送,并且由于其是异步且非阻塞的,并不会影响浏览器其他页面的显示效率。

sendBeacon只能发送http post请求。

问题:此方法无法自定义header信息,如果服务端设置了token权限拦截,sendBeacon并没有办法将token信息放入请求中。

3. fetch

window.addEventListener('beforeunload', () => {
    const url = 'test.com';
    const params = { test : 'test' }; 

    const headers = new Headers();
    headers.append('content-type', 'application/json');
    headers.append('token', 'token');        
    
    fetch(url, {
        method: 'POST',
        headers: headers,
        body: JSON.stringify(params),
        // 重要!!!
        keepalive: true,
    });
});
      

fetch方法配合参数中的keepalive字段会让浏览器在页面卸载后在后台继续接管网络请求,该字段是必须的。

此方法的缺陷为keepalive字段一次只能承载最大64KB的请求内容,且该限制是所有并行请求共享的,即,页面卸载阶段所有fetch+keepalive请求的内容体总和不能超过64KB。

参考文章

Sending AJAX Data when User Moves Away / Exits from Page

Fetch API

使用 Fetch - Web API 接口参考 | MDN

Navigator.sendBeacon() - Web API 接口参考 | MDN

javascript - Sending POST request with Fetch after closing the browser with 'beforeunload' / 'unload' eventlistener is not working - Stack Overflow​​​​​​​

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值