浏览器关闭请求
发表于:2023-11-08 |

前言

不知道大家平时有没有遇到过这样的需求

  1. 用户关闭浏览器或者刷新页面的时候,给用户一个提示,是否关闭浏览器或者刷新页面,如果用户点击了取消,那么就不进行操作,如果确定则进行操作。
  2. 刷新时不进行后续操作,关闭时需要给后台发送一个请求。

创建个普通的vue3项目

1
npm init vite 

这里就不多说了,直接进入正题

监听浏览器关闭刷新事件

监听beforeunload即可,具体的可以查询官方文档

1
2
3
4
5
window.addEventListener('beforeunload', function(event) {
// 拦截关闭事件
event.preventDefault();
event.returnValue = '';
});

此时我们浏览器的效果就如下:

到这里,我们其实已经把直接关闭给拦截住了,然而我们需要操作并不是在提示出来的时候进行操作,因为点击取消的时候我们是不需要进行发送请求的,所以,我们的代码不可能写成这样

1
2
3
4
5
6
7
window.addEventListener('beforeunload', function(event) {
// 拦截关闭事件
event.preventDefault();
event.returnValue = '';
// 发送请求
fetch("http://192.168.1.52:9527/test")
});

写一个nodejs服务

为了更好的观测是否发送了接口服务,我就先写了一个测试的node服务,大致步骤如下

  1. 新建一个文件夹里面创建index.js
  2. 使用vscode之类的打开,创建初始化包管理器,npm init -y
  3. 安装依赖express,这里大家可以使用自己喜欢的框架,比如koa之类的,我这里就用express了
  4. 书写index.js文件
  • 这里nodejs的知识后续有机会再和大家分享,这里大家就看我写的代码就好了,这里的意思是我基于我本地创建了一个模拟数据,通过9527端口的服务就可以访问
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    const express = require('express')
    const app = express()

    // 模拟返回数据
    const comebackData = [
    {
    name: 'jimson',
    age: 18,
    sex: '男'
    },
    {
    name: 'licy',
    age: 18,
    sex: '女'
    }
    ]

    // 定义接口
    app.get('/test', (req, res) => {
    res.status(200)
    console.log("我执行了")
    res.json(comebackData)
    })

    // 配置服务
    const server = app.listen(9527, () => {
    const host = server.address().address
    const port = server.address().port
    console.log("This app listen at http://%s:%s", host, port)
    })
  1. 启动服务,node index.js

服务启动

此时我们去访问我们的get请求就可以得到我们的数据了
服务启动

排除取消的情况

我们排除取消,当然就不可能在beforeunload发送我们的请求了,这时候可以留意一下另外一个apiunload,这是他的官网地址

这个api能让我们在页面刷新关闭的时候调用

1
2
3
4
5
6
7
8
9
window.addEventListener('beforeunload', function(event) {
// 拦截关闭事件
event.preventDefault();
event.returnValue = '';
});

window.addEventListener('unload', function() {
fetch('http://192.168.1.52:9527/test')
})

此时我们的效果就是这样的:

这时候我们就实现了我们的需求了,但是这里有个问题就是需求处理失败了会怎么样,我们就不考虑了,一句话,拦不住~

知识拓展

刷新发送请求

如果我们刷新页面的时候也想要去调用这个请求呢,就是页面第一次进来不需要,后续就需要了
这里就有很多种方式了:

  1. 第一种就是unload的时候也去调用,其实我们unload其实执行了,只是因为刷新导致页面重载了,请求被打断了,这时候我们给fetch加一个keepalive就可以保证接口发送出去

    1
    2
    3
    4
    5
    6
    7
    8
    9
    window.addEventListener('beforeunload', function(event) {
    // 拦截关闭事件
    event.preventDefault();
    event.returnValue = '';
    });

    window.addEventListener('unload', function() {
    fetch('http://192.168.1.52:9527/test',{keepalive:true})
    })

    这样也就让刷新的时候也成功调用接口了

  2. 另外一种思路就是判断是否是第一次进入页面的方法了,这里有很多
    第一种就是:window.performance.navigation.type == 1官方文档,
    现在已经改成了PerformanceNavigationTiming,官方文档

判断是刷新还是关闭

这里如果没用

1
2
3
4
5
window.addEventListener('beforeunload', function(event) {
// 拦截关闭事件
event.preventDefault();
event.returnValue = '';
});

代码进行拦截的话,我们可以使用时间差来判断

beforeunload定义一个当前时间Date now(),然后在unload里面定义一个Date now(),两个时间相减,如果小于5ms,就是关闭,不然就是刷新,就是这俩个api执行时间差比较小那就是关闭,时间差比较大就是刷新。

页面tab切换api

这里还有个api可以让我们知道用户是不是切换了tab,这个api就是visibilitychange官方文档,这个就不展开说了,感兴趣的小伙伴可以自己去看看

结语

今天文章就分享到这里了,更多内容敬请期待~

上一篇:
yarn等不生效
下一篇:
【Canvas学习】02-了解canvas(二)