废话不说,直接进正题。

最近项目有个需求需要在用户关闭页面时将页面存留的统计数据发送到后端。该需求有两个关键点:

  • 监听页面卸载
  • 在卸载时发送数据

如何监听用户关闭页面

首先我们需要明确,哪些场景属于用户关闭页面:

  • 关闭浏览器
  • 关闭/刷新页面

可监听上述场景的API为:

  • unload
  • beforeunload
  • pagehide
  • visibilitychange

但在许多情况下(尤其是移动设备)浏览器不会产生 unload、beforeunload 或 pagehide 事件。下面列出了一种不触发上述事件的情况:

  1. 用户加载了网页并与其交互。
  2. 完成浏览后,用户切换到了其它应用程序,而不是关闭选项卡。
  3. 随后,用户通过手机的应用管理器关闭了浏览器应用。

故此,我们采用visibilitychange + pagehide的组合方式监听用户行为。

if((typeof document.onvisibilitychange) !== 'undefined') {
	document.addEventListener('visibilitychange', function logData() {
	  if (document.visibilityState === 'hidden') {
	    // ... 发送数据
	  }
});
}else if((typeof window.onpagehide) !== 'undefined') {
	window.addEventListener("pagehide", event => {
	  if (event.persisted) {
	    /* the page isn't being discarded, so it can be reused later */
	  }
	}, false);
}

如何在卸载时发送数据

方法一: window.navigator.sendBeacon

语法

navigator.sendBeacon(url, data);

参数

  • url:表明 data 将要被发送到的网络地址。

  • data(可选): 将要发送的 ArrayBuffer、ArrayBufferView、Blob、DOMString、FormData 或 URLSearchParams 类型的数据。

返回值:当成功将数据加入传输队列返回true,否则返回false

示例

const blob = new Blob([JSON.stringify(data)], { type: 'application/json; charset=UTF-8'});
window.sendBeacon(url, blob);

其他

  • 数据限制:在大多浏览器上最多只能发送64kb的数据(亲测Chrome及Safari浏览器上最多发送64kb)。
  • 请求方法:通过POST请求发送数据。
  • 请求头: 通过传入数据data自动设置请求头,一般的: FormData: multipart/form-data,DomString: text/plain ,想传递json数据到后端,可以通过Blob对象间接达到设置Content-type的效果。

浏览器兼容

方法二: fetch设置keepalive为true

语法

Promise
fetch(input[, init]);

参数详见:fetch()-MDN

示例

fetch(url, { 
	body: data, 
	mode: 'no-cors', 
	method: 'POST', 
	headers: { 'Content-Type': 'application/json'}
}).then(response => response.json())
  .then(data => console.log(data));

其他

  • 数据限制:设置keepalive为true,最多只能发送64kb的数据(亲测Chrome及Safari浏览器上最多发送64kb)。

浏览器兼容

参考

原文地址:http://www.cnblogs.com/rainbowly/p/16908834.html

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长! 2. 分享目的仅供大家学习和交流,请务用于商业用途! 3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入! 4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解! 5. 如有链接无法下载、失效或广告,请联系管理员处理! 6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需! 7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员! 8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载 声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性