开发web应用程序过程当中的一种常见的作法,就是集中保存错误日志,以便查找重要错误的缘由.
就像数据库和服务器都会按期写入日志同样,在复杂的web应用程序中,咱们一样推荐你把JavaScript错误也回写到服务器,换句话再说,咱们也能够将这些错误写入到保存服务器端错误的地方,只不过标明他们来自前端.从而把前端的错误集中起来,能够及大地方便前端开发者分析代码.html
后端须要提供一个接收错误信息的接口,把接收到的错误信息存放在一个日志文件中,好比 font-msg.log.
前端在比较可能会出现错误的地方用 try{}catch(err){}
语句来捕获,而后经过一些能够发送请求的方法,把收集到的报错信息发送到这个后端提供的日志接口.
这样就获得了前端的报错日志了,开发者能够常常去查看,分析本身代码中的不足,优化改善代码.前端
前端代码中,咱们使用了Image对象来发送请求,这样作很是灵活,主要缘由以下:node
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>收集前端日志实例页面</title> <meta name="viewport" content="width=device-width,initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"/> </head> <body> <div>日志收集学习</div> </body> <script> // 发送错误日志的函数 function logError(sev, msg) { var img = new Image(); img.src = "http://127.0.0.1:4000/postMessage?sev=" + encodeURIComponent(sev) + "&msg=" + encodeURIComponent(msg); } try { for(var i = 0, len= mods.length; i < len; i++) { mods[i].init(); } } catch(ex) { // 捕捉错误信息 logError("nonfatal", "Module init failed: " + ex.message); } </script> </html>
补充:
评论里有朋友建议使用window.onerror事件,我在这里引用一下JavaScript高级程序设计(第三版)的书中对这个事件的解释:ios
任何没有经过try-catch处理的错误都会触发window对象的error事件,在任何web浏览器中,onerror事件处理程序都不会建立event对象,但它能够接收三个参数: 错误信息,错误所在的URL和行号.多数状况下,只有错误信息有用,由于URL只给出了文档的位置,而行号所指的代码既可能出自内部JavaScript代码,也可能出自外部文件.
只要发生错误,不管是否是浏览器生成的,都会触发error事件
window.onerror = function (message, url, line) { alert(message); return false; }
经过返回false,这个函数实际就充当了整个文档的try-catch语句,能够捕获全部无代码处理的运行错误.可是浏览器在使用这个事件处理错误的方式有明显不一样,在IE中,即便发生onerror事件,代码仍然会正常执行,全部变量和数据都将获得保留,所以能在onerror事件处理程序中访问它们,但在firefox中,常规代码会中止执行,事件发生以前的全部变量和数据都将被销毁,所以几乎就没法判断错误了,且另外window.onerror事件不能捕获promise的异常错误信息.
因此我在这里使用的是try...catch...,可是我以为具体的使用方法能够根据本身的业务需求来肯定,我这里只是作一个示例,实际的实现途径还有不少,可是万法同宗.
这里我使用node写了一个日志采集的接口,并将采集到的信息写入日志文件.laravel
app.js(主入口文件):git
const Koa = require("koa"); const app = new Koa(); const router = require('./router'); const axios = require('axios') app.use(router.routes()); app.use(router.allowedMethods()); app.on("error", function (err, ctx) { console.log(err) }) app.listen(4000, function (ctx) { console.log("i am listening"); })
router/index.js(路由入口文件):github
const koaRouter = require("koa-router"); const router = new koaRouter(); const log4js = require("log4js"); var config = { "replaceConsole": true, "appenders": { "stdout": { "type": "stdout" }, "req": { "type": "dateFile", "filename": "logs/reqlog/", "pattern": "req-yyyy-MM-dd.log", "alwaysIncludePattern": true }, "err": { "type": "dateFile", "filename": "logs/errlog/", "pattern": "err-yyyy-MM-dd.log", "alwaysIncludePattern": true }, "oth": { "type": "dateFile", "filename": "logs/othlog/", "pattern": "oth-yyyy-MM-dd.log", "alwaysIncludePattern": true } }, "categories": { "default": { "appenders": ["stdout", "req"], "level": "debug" }, "err": { "appenders": ["stdout", "err"], "level": "error" }, "oth": { "appenders": ["stdout", "oth"], "level": "info" } } } log4js.configure(config); const reqLogger = log4js.getLogger(); const errLogger = log4js.getLogger('err'); const infoLogger = log4js.getLogger('oth'); router.get("/postMessage", async(ctx, next) => { console.log(ctx.query); infoLogger.info(ctx.query.sev + "--" + ctx.query.msg); ctx.body = { msg: "i get it", code: 200 }; return next(); }) module.exports = router;
收集到的日志信息截图:web
更详细的代码: https://github.com/muzishuiji...数据库
推荐阅读:axios
不知道大家是怎样前端报错信息的呢?若是大家有更好的采集方法,欢迎email(2510909248@qq.com)或者私信给我,爱分享的你最可爱^_^^_^
若是个人文章中有不足之处,欢迎批评指正~~