1.vue 监听网页关闭/浏览器关闭事件

<script>

export default {
  name: 'App',
  mounted(){
    //添加监听事件
    window.addEventListener('beforeunload', e => this.beforeunloadHandler(e))
  },
  methods: {
    beforeunloadFn(e) {
      console.log('刷新或关闭')
      // ...
    }
  },
  created() {
    window.addEventListener('beforeunload', e => this.beforeunloadFn(e))
  },
  destroyed() {
    window.removeEventListener('beforeunload', e => this.beforeunloadFn(e))
  },

}
</script>

参考文章:https://blog.csdn.net/weixin_43915587/article/details/93628935?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522163720628816780265423678%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=163720628816780265423678&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allbaidu_landing_v2~default-1-93628935.pc_search_result_control_group&utm_term=vue%E8%8E%B7%E5%8F%96%E6%A0%87%E7%AD%BE%E9%A1%B5%E5%85%B3%E9%97%AD%E4%BA%8B%E4%BB%B6&spm=1018.2226.3001.4187

2.监听用户离开页面

<script>
export default {
  window:onblur = function () {
    console.log('失去焦点');
  },
  window:onfocus = function() {
    console.log('得到焦点');
  },
name: 'App',
  mounted(){
    //添加监听事件
    window.addEventListener('beforeunload', e => this.beforeunloadHandler(e));

    document.addEventListener('visibilitychange',function(e){
      console.log(document.visibilityState);
      let state = document.visibilityState
      if(state == 'hidden'){
        console.log(document.visibilityState,'用户离开了');
      }
      if(state == 'visible'){
        console.log(document.visibilityState,'回来了');
      }
    });

  }
</script>

3.关闭浏览器,向后端提交数据(研究websocket心跳长链接)

I. 直接发送 xhr 请求

我们会优先想到监听页面的unload或者beforeunload事件,在事件回调里使用XMLHttpRequest发送异步请求。

但是由于是xhr请求是异步发送,很可能在它即将发送的时候,页面已经卸载了,从而导致发送取消或者发送失败。异步请求响应返回后,由于页面和相关资源已经卸载,会引起function not found的错误。

解决方法就是 AJAX 通信改成同步发送,即只有发送完成,页面才能卸载。

const syncReport = (url, { data = {}, headers = {} } = {}) => {
  const xhr = new XMLHttpRequest();
  xhr.open('POST', url, false);
  xhr.withCredentials = true;
  Object.keys(headers).forEach((key) => {
    xhr.setRequestHeader(key, headers[key]);
  });
  xhr.send(JSON.stringify(data));
};

xhr请求改为同步,虽然能够完成发送数据,但存在以下两个问题:

  1. 部分浏览器已经不支持同步的 XMLHttpRequest 对象了(即open()方法的第三个参数为false);
  2. xhr请求改为同步后,会阻塞页面的卸载和跳转,导致下一个页面导航加载的时机变晚,用户体验较差。

II.Navigator.sendBeacon

浏览器引入的sendBeacon方法,**发出的是异步请求,但是请求是作为浏览器任务执行的,与当前页面是脱钩的。**因此该方法不会阻塞页面卸载流程和延迟后面页面的加载。
1. 基本用法

navigator.sendBeacon(url, data);

url 就是上报地址,data 可以是 ArrayBufferViewBlobDOMStringFormdata,根据官方规范,需要 request header 为 CORS-safelisted-request-header,在这里则需要保证 Content-Type 为以下三种之一:

  • application/x-www-form-urlencoded
  • multipart/form-data
  • text/plain

我们一般会用到 DOMString , BlobFormdata 这三种对象作为数据发送到后端,下面以这三种方式为例进行说明。

// 1. DOMString类型,该请求会自动设置请求头的 Content-Type 为 text/plain
const reportData = (url, data) => {
  navigator.sendBeacon(url, data);
};

关闭页面,提交数据,文章参考:https://blog.csdn.net/u010671652/article/details/103498492

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐