使用Web Beacon API进行活动记录


信标API是基于JavaScript的接口,用于:


从浏览器向服务器发送少量数据,而无需等待响应。 在本文中,我们将考虑Beacon API在什么情况下会有用,它与出于相同目的使用XMLHTTPRequest (Ajax)有何区别以及如何使用它。


为什么我们需要另一个API?


信标API用于将小数据发送到服务器, 而无需等待响应 。 声明的最后一部分是最有趣的。 信标API专为发送数据而忽略它而设计。 永远都不会期望得到答案。


明信片的隐喻,是人们相互发送/发送的卡片。 通常,他们在上面写下一小段文字(“你在哪里?我在海上很开心。”,“这里天气很好,不像你在办公室里的样子”),他们把它们扔在邮件里,忘了。 没有人期望得到这样的回答:“我已经离开你了,”“在我办公室里真是太好了。”


在许多情况下,“发送并忘记”方法是合适的。


统计跟踪和分析信息


这是想到的第一件事。 诸如Google Analytics(分析)之类的大型解决方案可以很好地概述基本知识。 但是,如果我们想要更多定制的东西? 我们需要编写一些代码来跟踪页面上发生的事情(用户与组件的交互方式,滚动的距离,首次销售之前显示的页面),然后在用户离开页面时将此数据发送到服务器。 信标非常适合执行此任务,因为我们仅发送数据,不需要服务器的响应。


调试和记录


另一个应用程序是从JavaScript代码记录信息。 想象一下当您的大型应用程序具有丰富的UI / UX时的情况。 所有测试均为绿色,并且该错误会定期在您知道的专业人士上弹出,但由于缺少信息,您无法执行此操作。 在这种情况下,您可以使用信标进行诊断。


实际上,任何带有日志记录的任务都可以使用信标解决。 这可以是在游戏中创建保存点,收集有关使用新功能的信息,记录测试结果等等。 如果这是浏览器中发生的事情,并且您希望服务器知道这一点,那么Beacon就是您所需要的。


我们以前没有这样做吗?


我知道你在想什么 这些都不是新的吗? 十多年来,我们一直通过XMLHTTPRequest与北方进行通信。 我们最近开始使用Fetch API,实际上与新的Promise接口相同。 那么,为什么我们需要另一个Beacon API?


关键功能是我们不需要服务器的响应。 浏览器可以将请求排队并发送数据,而不会阻止任何代码的执行。 由于浏览器可以利用此功能,因此代码是否仍在运行对我们而言都无关紧要,浏览器将简单地将请求静默发送到后台。


C Beacon API不需要等待CPU网络的最佳时机。 仅使用信标将请求添加到队列实际上是毫无价值的。


要了解为什么这很重要,只需查看通常使用这种逻辑的方式和位置。 例如,为了衡量用户在页面上的停留时间,我们需要在会话结束时尽可能近地向服务器发送请求。


这通常是在unloadbeforeunload 。 此类代码可能会阻止执行,并且如果页面延迟,则下一页的加载也会延迟。 这导致不是最好的用户体验。


您了解HTTP请求的速度如何吗? 最后,您想要在转换之间推送HTTP请求。


尝试Beacon API


基本用法示例非常简单:


 let result = navigator.sendBeacon(url, data); 

result布尔值。 如果浏览器已将请求添加到队列中,则为true ,否则为false


使用navigator.sendBeacon()


navigator.sendBeacon接受两个参数。 第一个是将请求发送到的URL,第二个是必须发送的数据。 该请求具有HTTP POST的形式。


data此参数可以接受Fetch API可以使用的几种数据格式。 它可以是Blob,BufferSource,FormData或URLSearchParams等。


我喜欢将FormData用于简单的键值数据,它不是一个复杂且易于使用的类。


 // URL    let url = '/api/my-endpoint'; //   FormData let data = new FormData(); data.append('hello', 'world'); let result = navigator.sendBeacon(url, data); if (result) { console.log('  !'); } else { console.log('.'); } 

浏览器支持


对该API的支持非常可靠。 唯一不支持的浏览器是Internet Explorer(我没有想到)和Opera Mini。 但是在Edge中一切正常。 在大多数情况下,都有支持,但最好检查一下以防万一:


 if (navigator.sendBeacon) { // Beacon  } else { //  XHR? } 

示例:记录在页面上花费的时间


为了在实践中看到全部内容,我们创建一个简单的系统来计算用户在页面上的停留时间。 页面加载时,我们查看时间,页面离开时,我们从查看开始就发送请求并将当前请求发送到服务器。


由于我们只对花费在页面上的时间感兴趣,而不是对现在的时间感兴趣,因此可以在加载页面时使用performance.now()获取基本时间戳:


 let startTime = performance.now(); 

让我们在一个易于使用的函数中包装一小段逻辑:


 let logVisit = function() { // Test that we have support if (!navigator.sendBeacon) return true; // URL to send the data to, eg let url = '/api/log-visit'; // Data to send let data = new FormData(); data.append('start', startTime); data.append('end', performance.now()); data.append('url', document.URL); // Let's go! navigator.sendBeacon(url, data); }; 

最后,我们需要在用户离开页面时调用此函数。 首先想到的是使用unload ,但是出于安全原因,Mac上的Safari似乎阻止了该请求。 因此,最好使用beforeunload


 window.addEventListener('beforeunload', logVisit); 

卸载页面时(或之前),将调用我们的logVisit()函数,如果浏览器支持Beacon API,它将向服务器发送请求。


几点


由于将使用Beacon API的大多数问题都与活动跟踪有关,因此,重要的是要注意整个厨房的社会和法律部分。


GDPR


只要记住它。


DNT:请勿追踪


此外,浏览器还具有一个选项,允许用户指示他们不想跟踪其活动。 Do Not Track发送的HTTP标头如下所示:


 DNT: 1 

如果您正在跟踪可以指示用户的数据,并且请求标头具有DNT: 1 ,那么最好监听用户而不保存任何数据。 例如,使用PHP,可以按以下步骤进行验证:


 if (!empty($_SERVER['HTTP_DNT'])) { //  ,   } 

总结


信标API确实是将数据发送到服务器的一种非常方便的方法,尤其是在日志记录的情况下。 浏览器支持水平足够高,可让您轻松记录任何信息,而不会对UI的性能和响应性造成任何负面影响。 这些请求的非阻塞性质在其中起着非常重要的作用;它比XHR和Fetch的替代方案要快得多。


Source: https://habr.com/ru/post/zh-CN419137/


All Articles