网络-navigator.sendBeacon


文章目录

  • 前言
  • 一、navigator.sendBeacon是什么?
    • 优点
    • 缺点
  • 二、navigator.sendBeacon应用场景
  • 三、navigator.sendBeacon的使用
  • 四、用户停留时间埋点
  • 总结


前言

本文主要记录navigator.sendBeacon异步请求的使用,以及应用场景和埋点小demo。


一、navigator.sendBeacon是什么?

navigator.sendBeacon 是一个浏览器 API,用于在浏览器后台发送异步请求,不会等服务端响应。
它可以用于在页面卸载或关闭时发送数据,以及在不阻塞页面卸载的情况下发送数据。
使用 navigator.sendBeacon 方法发送的请求是异步的,不会阻塞页面的卸载或关闭过程。
这对于需要在用户离开页面之前发送数据的情况非常有用。

优点

  • 不受页面卸载过程的影响,确保数据可靠发送
    普通的http请求如XMLHttpRequest Fetch在页面关闭或者刷新、前进、后退等操作时这些请求有可能在页面销毁之前没有完成,导致数据丢失。也可以控制页面销毁延后,这就导致页面销毁时间增加。
  • 异步执行,不阻塞页面关闭或者跳转
    navigator.sendBeacon的优先级是较低的,XMLHttpRequest Fetch这些同步请求,以及其他高优先级任务在它之前,navigator.sendBeacon并不会立即执行,可以说它会在空闲时间发送请求。
  • 能够发送跨域请求
    navigator.sendBeacon是不受跨域限制的

缺点

  • 只能发送POST请求
  • 只能传输少量数据(64 KB以内)
  • 无法自定义请求头
  • 只能传输ArrayBufferArrayBufferViewBlobDOMStringFormDataURLSearchParams类型数据
  • 如果处于危险网络环境、开启了广告屏蔽插件 该请求将无效

二、navigator.sendBeacon应用场景

  • 发送心跳包
    利用navigator.sendBeacon发送心跳包,与服务器保持长连接,避免长时间未请求而断开连接。
function sendHeartbeat() {
  const data = 'heartbeat'; // 心跳包数据
  const url = 'http://localhost:3001/api/heartbeat'; // 心跳包目标 URL

  navigator.sendBeacon(url, data);
}

// 每隔一定时间发送心跳包
setInterval(sendHeartbeat, 5000); // 每 5 秒发送一次心跳包

网络-navigator.sendBeacon_第1张图片

  • 埋点
    可以使用navigator.sendBeacon在页面卸载时记录停留时间,以及pv、uv、错误日志的上报、按钮点击次数等
  • 用户反馈
    对于一些小的表单,如:用户反馈、意见和建议等可以使用navigator.sendBeacon进行请求。
    网络-navigator.sendBeacon_第2张图片

三、navigator.sendBeacon的使用

基本语法如下:

navigator.sendBeacon(url, data);
  • url: 是要发送请求的目标地址,可以是相对路径或绝对 URL。
  • data: 是要发送的数据,可以是字符串、ArrayBuffer 或 Blob。

navigator.sendBeacon 方法发送的请求是 POST 请求,并且请求头中会自动添加 Content-Type: application/x-www-form-urlencoded。

需要发送JSON格式的数据的时候,可以使用Blob进行包装从而发送JSON数据

let data = {name:"smz"}
let blob = new Blob([JSON.stringify(data)],{type:'application/json; charset=UTF-8'})

四、用户停留时间埋点

当打开页面时记录时间,在页面销毁的时候记录时间,这样就得到了用户停留时间,再通过navigator.sendBeacon进行上报用户名、时间、页面等信息完成数据的统计。

前端:

const reportData = () =>{
    //统计停留时间
    let startTime = performance.now(); // 进入页面的时间点
    let logVisit = async function() {
        if (!navigator.sendBeacon) return false;

        const endTime = performance.now(); // 页面卸载的时间点

        let data = new FormData();
        const reportDataList = {
            name: 'smz',
            page: 'home',
            stayTime: ((endTime - startTime)/60000).toFixed(2) + '分钟' // 用户停留时间
        };
        let time = new Blob([JSON.stringify(reportDataList)],{type:'application/json; charset=UTF-8'})
        navigator.sendBeacon("http://localhost:3001/api/b", time);
    };
    window.addEventListener("beforeunload", logVisit);
}
reportData()

后端:这里使用node

const express = require('express')
const app = express()

app.use((req, res, next) => {
    res.setHeader('Access-Control-Allow-Origin', 'http://localhost:63342');
    res.setHeader('Access-Control-Allow-Credentials', true);
    res.setHeader("Access-Control-Allow-Headers", "Content-Type,XFILENAME,XFILECATEGORY,XFILESIZE");
    next();
});

// 解析req.body中的内容
app.use(express.text())
// 心跳包
app.post('/api/heartbeat',(req,res)=>{
    console.log(req.body)
    res.send('ok')
})

// 解析req.body中的内容
app.use(express.json())

// navigator.sendBeacon
app.post('/api/b',(req,res)=>{
    console.log(req.body)
    res.send('ok')
})

app.listen(3001,()=>{
    console.log('server is running')
})

网络-navigator.sendBeacon_第3张图片


总结

总之,navigator.sendBeacon 是一个方便的浏览器 API,用于在页面卸载或关闭时发送异步请求,适用于发送统计数据、日志记录、表单提交等场景。

你可能感兴趣的:(网络,网络)