媒介
開闢web應用順序過程當中的一種罕見的做法,就是集合保存毛病日記,以便查找重要毛病的緣由.
就像數據庫和服務器都邑按期寫入日記一樣,在龐雜的web應用順序中,我們一樣引薦你把JavaScript毛病也回寫到服務器,換句話再說,我們也能夠將這些毛病寫入到保存服務器端毛病的處所,只不過標明他們來自前端.從而把前端的毛病集合起來,能夠及大處所便前端開闢者剖析代碼.
細緻操作
重要頭腦
後端須要供應一個吸收毛病信息的接口,把吸收到的毛病信息存放在一個日記文件中,比方 font-msg.log.
前端在比較能夠會湧現毛病的處所用 try{}catch(err){}
語句來捕獲,然後經由過程一些能夠發送要求的要領,把網絡到的報錯信息發送到這個後端供應的日記接口.
如許就獲得了前端的報錯日記了,開闢者能夠經常去檢察,剖析本身代碼中的不足,優化改良代碼.
代碼示例
前端代碼示例
前端代碼中,我們運用了Image對象來發送要求,如許做非常天真,重要緣由以下:
- 一切瀏覽器都支撐Image對象;
- 能夠防止跨域限定,img的src屬性能夠完成跨域接見.
- 在紀錄毛病的過程當中出問題的幾率比較低.
<!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高等順序設計(第三版)的書中對這個事宜的詮釋:
任何沒有經由過程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寫了一個日記收集的接口,並將收集到的信息寫入日記文件.
app.js(主進口文件):
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(路由進口文件):
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;
網絡到的日記信息截圖:
更細緻的代碼: https://github.com/muzishuiji…
引薦瀏覽:
不知道你們是如何前端報錯信息的呢?假如你們有更好的收集要領,迎接email(2510909248@qq.com)或許私信給我,愛分享的你最可愛^_^^_^
假如我的文章中有不足之處,迎接批評指正~~