javascript基础从小白到高手系列二千二百五十五:Beacon API
38/100
发布文章
wanmeijuhao
未选择任何文件
为了把尽量多的页面信息传到服务器,很多分析工具需要在页面生命周期中尽量晚的时候向服务器
发送遥测或分析数据。因此,理想的情况下是通过浏览器的unload 事件发送网络请求。这个事件表示
用户要离开当前页面,不会再生成别的有用信息了。
在unload 事件触发时,分析工具要停止收集信息并把收集到的数据发给服务器。这时候有一个问题,
因为unload 事件对浏览器意味着没有理由再发送任何结果未知的网络请求(因为页面都要被销毁了)。
例如,在unload 事件处理程序中创建的任何异步请求都会被浏览器取消。为此,异步XMLHttpRequest
或fetch()不适合这个任务。分析工具可以使用同步XMLHttpRequest 强制发送请求,但这样做会导
致用户体验问题。浏览器会因为要等待unload 事件处理程序完成而延迟导航到下一个页面。
为解决这个问题,W3C 引入了补充性的Beacon API。这个API 给navigator 对象增加了一个
sendBeacon()方法。这个简单的方法接收一个URL 和一个数据有效载荷参数,并会发送一个POST
请求。可选的数据有效载荷参数有ArrayBufferView、Blob、DOMString、FormData 实例。如果请
求成功进入了最终要发送的任务队列,则这个方法返回true,否则返回false。
可以像下面这样使用这个方法:
// 发送POST 请求
// URL: ‘https://example.com/analytics-reporting-url’
// 请求负载:‘{foo: “bar”}’
navigator.sendBeacon(‘https://example.com/analytics-reporting-url’, ‘{foo: “bar”}’);
这个方法虽然看起来只不过是POST 请求的一个语法糖,但它有几个重要的特性。
sendBeacon()并不是只能在页面生命周期末尾使用,而是任何时候都可以使用。
调用sendBeacon()后,浏览器会把请求添加到一个内部的请求队列。浏览器会主动地发送队
列中的请求。
浏览器保证在原始页面已经关闭的情况下也会发送请求。
状态码、超时和其他网络原因造成的失败完全是不透明的,不能通过编程方式处理。
信标(beacon)请求会携带调用sendBeacon()时所有相关的cookie。
Web Socket
Web Socket(套接字)的目标是通过一个长时连接实现与服务器全双工、双向的通信。在JavaScript
中创建Web Socket 时,一个HTTP 请求会发送到服务器以初始化连接。服务器响应后,连接使用HTTP
的Upgrade 头部从HTTP 协议切换到Web Socket 协议。这意味着Web Socket 不能通过标准HTTP 服务
器实现,而必须使用支持该协议的专有服务器。
因为Web Socket 使用了自定义协议,所以URL 方案(scheme)稍有变化:不能再使用http://或https://,
而要使用ws://和wss://。前者是不安全的连接,后者是安全连接。在指定Web Socket URL 时,必须包
含URL 方案,因为将来有可能再支持其他方案。
使用自定义协议而非HTTP 协议的好处是,客户端与服务器之间可以发送非常少的数据,不会对
HTTP 造成任何负担。使用更小的数据包让Web Socket 非常适合带宽和延迟问题比较明显的移动应用。
使用自定义协议的缺点是,定义协议的时间比定义JavaScript API 要长。Web Socket 得到了所有主流浏
览器支持。
API
要创建一个新的Web Socket,就要实例化一个WebSocket 对象并传入提供连接的URL:
let socket = new WebSocket(“ws://www.example.com/server.php”);
注意,必须给WebSocket 构造函数传入一个绝对URL。同源策略不适用于Web Socket,因此可以
打开到任意站点的连接。至于是否与来自特定源的页面通信,则完全取决于服务器。(在握手阶段就可
以确定请求来自哪里。)
浏览器会在初始化WebSocket 对象之后立即创建连接。与XHR 类似,WebSocket 也有一个
readyState 属性表示当前状态。不过,这个值与XHR 中相应的值不一样。
WebSocket.OPENING(0):连接正在建立。
WebSocket.OPEN(1):连接已经建立。
WebSocket.CLOSING(2):连接正在关闭。
WebSocket.CLOSE(3):连接已经关闭。
WebSocket 对象没有readystatechange 事件,而是有与上述不同状态对应的其他事件。
readyState 值从0 开始。
任何时候都可以调用close()方法关闭Web Socket 连接:
socket.close();
调用close()之后,readyState 立即变为2(连接正在关闭),并会在关闭后变为3(连接已经关闭)。
为了把尽量多的页面信息传到服务器,很多分析工具需要在页面生命周期中尽量晚的时候向服务器
发送遥测或分析数据。因此,理想的情况下是通过浏览器的unload 事件发送网络请求。这个事件表示
用户要离开当前页面,不会再生成别的有用信息了。
在unload 事件触发时,分析工具要停止收集信息并把收集到的数据发给服务器。这时候有一个问题,
因为unload 事件对浏览器意味着没有理由再发送任何结果未知的网络请求(因为页面都要被销毁了)。
例如,在unload 事件处理程序中创建的任何异步请求都会被浏览器取消。为此,异步XMLHttpRequest
或fetch()不适合这个任务。分析工具可以使用同步XMLHttpRequest 强制发送请求,但这样做会导
致用户体验问题。浏览器会因为要等待unload 事件处理程序完成而延迟导航到下一个页面。
为解决这个问题,W3C 引入了补充性的Beacon API。这个API 给navigator 对象增加了一个
sendBeacon()方法。这个简单的方法接收一个URL 和一个数据有效载荷参数,并会发送一个POST
请求。可选的数据有效载荷参数有ArrayBufferView、Blob、DOMString、FormData 实例。如果请
求成功进入了最终要发送的任务队列,则这个方法返回true,否则返回false。
可以像下面这样使用这个方法:
// 发送POST 请求
// URL: ‘https://example.com/analytics-reporting-url’
// 请求负载:‘{foo: “bar”}’
navigator.sendBeacon(‘https://example.com/analytics-reporting-url’, ‘{foo: “bar”}’);
这个方法虽然看起来只不过是POST 请求的一个语法糖,但它有几个重要的特性。
sendBeacon()并不是只能在页面生命周期末尾使用,而是任何时候都可以使用。
调用sendBeacon()后,浏览器会把请求添加到一个内部的请求队列。浏览器会主动地发送队
列中的请求。
浏览器保证在原始页面已经关闭的情况下也会发送请求。
状态码、超时和其他网络原因造成的失败完全是不透明的,不能通过编程方式处理。
信标(beacon)请求会携带调用sendBeacon()时所有相关的cookie。
Web Socket
Web Socket(套接字)的目标是通过一个长时连接实现与服务器全双工、双向的通信。在JavaScript
中创建Web Socket 时,一个HTTP 请求会发送到服务器以初始化连接。服务器响应后,连接使用HTTP
的Upgrade 头部从HTTP 协议切换到Web Socket 协议。这意味着Web Socket 不能通过标准HTTP 服务
器实现,而必须使用支持该协议的专有服务器。
因为Web Socket 使用了自定义协议,所以URL 方案(scheme)稍有变化:不能再使用http://或https://,
而要使用ws://和wss://。前者是不安全的连接,后者是安全连接。在指定Web Socket URL 时,必须包
含URL 方案,因为将来有可能再支持其他方案。
使用自定义协议而非HTTP 协议的好处是,客户端与服务器之间可以发送非常少的数据,不会对
HTTP 造成任何负担。使用更小的数据包让Web Socket 非常适合带宽和延迟问题比较明显的移动应用。
使用自定义协议的缺点是,定义协议的时间比定义JavaScript API 要长。Web Socket 得到了所有主流浏
览器支持。
API
要创建一个新的Web Socket,就要实例化一个WebSocket 对象并传入提供连接的URL:
let socket = new WebSocket(“ws://www.example.com/server.php”);
注意,必须给WebSocket 构造函数传入一个绝对URL。同源策略不适用于Web Socket,因此可以
打开到任意站点的连接。至于是否与来自特定源的页面通信,则完全取决于服务器。(在握手阶段就可
以确定请求来自哪里。)
浏览器会在初始化WebSocket 对象之后立即创建连接。与XHR 类似,WebSocket 也有一个
readyState 属性表示当前状态。不过,这个值与XHR 中相应的值不一样。
WebSocket.OPENING(0):连接正在建立。
WebSocket.OPEN(1):连接已经建立。
WebSocket.CLOSING(2):连接正在关闭。
WebSocket.CLOSE(3):连接已经关闭。
WebSocket 对象没有readystatechange 事件,而是有与上述不同状态对应的其他事件。
readyState 值从0 开始。
任何时候都可以调用close()方法关闭Web Socket 连接:
socket.close();
调用close()之后,readyState 立即变为2(连接正在关闭),并会在关闭后变为3(连接已经关闭)。
Markdown 2036 字数 54 行数 当前行 1, 当前列 0HTML 2036 字数 53 段落
发布博文获得大额流量券