❀ 日志上报的特点
日志收集的功能业务优先级比较低,不应该阻塞其他功能的运行
日志上报不关心响应,只需要把数据发出去就可以了
❀ 直接发 request 请求
client > nginx > server >>> client
日志量大的时候对服务器压力山大
流量消耗不容小觑
可能会阻塞页面,用户体验有风险
❀ 通过创建图片元素来发起请求
以图片为载体,不存在跨域被拦截的问题,也不会阻塞页面
服务器只需要返回一个最小单元的图片就可以保证极小的流量消耗
同样都是 1x1 像素大小的图片,gif 的体积是最小的,大概只有 43 字节
在 beforeunload 中创建图片可以延迟卸载以保障图片加载,但是这样会对用户体验有一些影响
利用 nginx 就可以完成日志的收集,不需要转发到后端做处理,所以超快的
前端通过 Image 发起图片请求,兼容性好
(new Image()).src= '//log.com/a.gif?x=1&y=kk..'
百度打点就是发的 gif 请求
❀ 尝试建一个简单的日志收集服务 nginx.confhttp { ... ... log_format logjson escape=json '{ "request": "$request", "time_local": "$time_local", "remote_addr": "$remote_addr", "body_bytes_sent": $body_bytes_sent, "status": $status }'; access_log logs/access.log logjson; server { listen 80; listen 443 ssl; server_name local.test.com; index index.html; location = /b.gif { add_header Cache-Control no-store; empty_gif; } }}
empty_gif 可以返回一个 1x1 的透明 gif 图片
log_format 设置日志格式
log_format name [escape=default|json|none] string ...;
name - 格式名,不可重复
string - 详细的格式定义,可以使用 $ 开头的变量
access_log path [format [buffer=size] [gzip[=level]] [flush=time] [if=condition]];access_log off;
服务端只需要定时去获取 log 文件,并解析里面的数据就可以了
nginx 请求静态资源默认不支持 POST 方法
❀ 通过 navigator.sendBeacon 发送数据
用于通过 HTTP 将少量数据异步传输到 Web 服务器
请求以 POST 方法发送
利用用户代理将请求加入浏览器的任务队列,接下来就交给浏览器自行处理了
用户代理在浏览器空闲时,在后台无阻塞地发起请求
不会阻塞页面,也不会影响页面的性能
因此即使在 unload 或 beforeunload 事件中也可以放心使用
url - 请求地址
data - 请求参数,根据 data 类型不同 Content-Type 也会不同
navigator.sendBeacon('//log.com/b.gif', data)
试一试byMe