javascript如何实现前端日志记录_如何将错误信息上报到服务器?

16次阅读

前端捕获未处理js错误需同时监听window.onError、addEventListener(‘error’)和unhandledrejection事件,用Beacon API优先上报,辅以采样去重和上下文快照。

javascript如何实现前端日志记录_如何将错误信息上报到服务器?

前端日志怎么捕获未处理的 JS 错误?

直接监听 window.onerrorwindow.addEventListener('error') 是最基础也最可靠的入口,但二者覆盖范围不同:window.onerror 捕获全局同步错误(如语法错误、运行时异常),而 addEventListener('error') 主要捕获资源加载失败(javascript如何实现前端日志记录_如何将错误信息上报到服务器? 等)。

必须同时注册两者,否则会漏掉大量错误。尤其注意:promise 拒绝(unhandledrejection)需单独监听,它不会触发前两者。

  • window.onerror 回调参数顺序固定:(message, source, lineno, colno, error),其中 error 是原生 Error 实例,可取 error.stack
  • unhandledrejection 事件的 event.reason 可能是字符串Error,需统一转为对象再提取
  • 不要在这些监听器里执行复杂逻辑或发起多个请求,避免阻塞或引发新错误

如何把错误数据可靠地发到服务器?

fetch 发送日志看似简单,但默认不带凭证、可能被 CORS 拦截、失败后无重试——这会导致大量错误“静默丢失”。关键不是“发出去”,而是“确保发成功”。

  • 优先用 Beacon APInavigator.sendBeacon()):页面卸载时仍能异步发出,不阻塞关闭,且自动携带 cookie(如果后端允许)
  • 若不支持 Beacon(如旧版 safari),降级用 fetch(..., { keepalive: true }),但需确认浏览器兼容性
  • 绝对避免在 beforeunload 中用普通 fetchXMLhttpRequest:多数浏览器会中止请求
  • 上报 payload 应精简:只传 messagestackurluserAgenttimestamp 和必要业务上下文(如当前路由、用户 ID)

如何避免日志上报干扰正常业务或触发限流?

前端错误常呈爆发式(如 CDN 失效导致全站脚本报错),不做节流会压垮后端接口,甚至拖慢页面。必须在客户端做采样和缓冲。

立即学习Java免费学习笔记(深入)”;

  • 对同一错误(基于 message + stack 哈希)做 5 分钟内去重,避免重复上报
  • 启用随机采样(如 math.random() )控制整体上报率,线上环境建议 ≤ 10%
  • 错误积压时用内存队列暂存(如最多缓存 20 条),配合定时器批量发送,减少请求数
  • 上报接口必须返回 HTTP 2xx 才算成功;非 2xx 响应(包括网络失败)应计入失败计数,并尝试降级(如改用 Image ping 方式打点)
const logQueue = []; let isSending = false;  function enqueueLog(log) {   if (logQueue.length >= 20) return;   logQueue.push(log);   if (!isSending) sendBatch(); }  function sendBatch() {   if (logQueue.length === 0) return;   isSending = true;    const payload = { logs: logQueue.splice(0, 10) };      if (navigator.sendBeacon) {     navigator.sendBeacon('/api/log', JSON.stringify(payload));     isSending = false;   } else {     fetch('/api/log', {       method: 'POST',       headers: { 'Content-Type': 'application/json' },       body: JSON.stringify(payload),       keepalive: true     }).finally(() => {       isSending = false;       if (logQueue.length > 0) setTimeout(sendBatch, 100);     });   } }

上报链路里最容易被忽略的是「错误上下文丢失」:比如用户在表单提交后报错,但没记录当时输入了什么。这类信息不能全量上报(涉及隐私),但可设计白名单字段(如表单项 name 属性)做脱敏快照——这个动作得在错误发生前就埋好钩子,而不是等 onerror 触发才去抓。

text=ZqhQzanResources