返回

页面关闭也能发请求?navigator.sendBeacon 和 fetch keepalive 了解一下

前端

在页面关闭时安全可靠地发送 API 请求:navigator.sendBeacon 与 fetch keepalive

在前端开发中,有时我们需要在页面销毁(关闭/刷新)时将数据同步给后台,比如记录视频播放进度、用户行为日志等。传统的做法是使用 AJAX 请求,但在页面关闭时,AJAX 请求可能会被中断,导致数据丢失。

为了解决这个问题,我们可以使用 navigator.sendBeaconfetch keepalive 这两个强大的工具。它们可以在页面关闭时将数据安全可靠地发送到服务器,保证数据的完整性和准确性。

navigator.sendBeacon

navigator.sendBeacon 是一个异步 API,它可以在页面关闭时发送数据到服务器。它的语法如下:

navigator.sendBeacon(url, data);
  • url 是要发送数据的服务器端 URL。
  • data 是要发送的数据。它可以是字符串、Blob 或 FormData 对象。

当调用 navigator.sendBeacon 时,浏览器会创建一个新的 HTTP 请求,并将数据发送到服务器。即使页面已经关闭,请求也会继续发送,直到数据被成功发送到服务器。

代码示例:

navigator.sendBeacon('https://example.com/log', '{"event": "page_closed"}');

fetch keepalive

fetch keepalive 是一个新的特性,它允许我们在页面关闭时保持一个 HTTP 请求的连接。它的语法如下:

fetch(url, {
  keepalive: true
});
  • url 是要发送数据的服务器端 URL。
  • keepalive 是一个布尔值,表示是否保持连接。

当我们调用 fetch keepalive 时,浏览器会创建一个新的 HTTP 请求,并将连接保持打开状态。即使页面已经关闭,连接也会继续保持,直到数据被成功发送到服务器。

代码示例:

fetch('https://example.com/log', {
  keepalive: true,
  method: 'POST',
  body: '{"event": "page_closed"}'
});

使用场景

navigator.sendBeaconfetch keepalive 可以用于各种场景,比如:

  • 记录视频播放进度
  • 记录用户行为日志
  • 发送分析数据
  • 同步本地数据到服务器

优缺点

navigator.sendBeaconfetch keepalive 都有各自的优缺点。

navigator.sendBeacon

  • 优点:
    • 可以发送任意类型的数据
    • 可以跨域发送数据
    • 在页面关闭时也能发送数据
  • 缺点:
    • 不支持请求头
    • 不支持响应数据

fetch keepalive

  • 优点:
    • 支持请求头
    • 支持响应数据
  • 缺点:
    • 只能发送字符串数据
    • 不能跨域发送数据

总结

navigator.sendBeaconfetch keepalive 都是非常强大的工具,它们可以帮助我们轻松实现页面关闭时发送 API 请求。我们可以根据自己的需要选择合适的工具来使用。

常见问题解答

1. navigator.sendBeacon 和 fetch keepalive 有什么区别?

navigator.sendBeacon 可以发送任意类型的数据,在页面关闭时也能发送数据,但不支持请求头和响应数据;而 fetch keepalive 支持请求头和响应数据,但只能发送字符串数据,且不能跨域发送数据。

2. navigator.sendBeacon 可以发送多少数据?

没有限制,但不同的浏览器可能会有不同的限制。

3. fetch keepalive 可以保持连接多长时间?

连接可以保持到浏览器关闭或服务器关闭为止。

4. navigator.sendBeacon 和 fetch keepalive 哪个更好?

这取决于你的具体需要。如果你需要发送任意类型的数据,并且在页面关闭时也能发送数据,那么可以使用 navigator.sendBeacon;如果你需要支持请求头和响应数据,那么可以使用 fetch keepalive

5. 如何使用 navigator.sendBeacon 记录视频播放进度?

你可以每隔一段时间使用 navigator.sendBeacon 发送当前播放进度到服务器。