這個不是很經常使用的功能, 可是想收集客戶端的錯誤信息時卻頗有必要了解下。 捕獲分爲兩個方面:
最初的是想直接獲取控制檯的錯誤信息; 然而這並不大可行,JS並無這樣的功能。 javascript
轉換下思路java
在錯誤發生時,將錯誤進行存儲。git
經過重載 window 對象下的 onerror 函數, 能夠截取到這些信息。github
window.onerror = function(errorMessage, scriptURI, lineNumber,columnNumber,errorObj) { console.log("錯誤信息:" , errorMessage); console.log("出錯文件:" , scriptURI); console.log("出錯行號:" , lineNumber); console.log("出錯列號:" , columnNumber); console.log("錯誤詳情:" , errorObj); }
只在angular 下作了實現,沒有實現過的框架沒有發言權;接下來將以angular爲例。但要注意的是在部分框下這種方式是不生效的,緣由是在框架解析代碼前,全部的代碼能夠理解爲都是文本而非js文件。
angular 環境下沒法使用window.ondrror. 緣由是angular體制內的代碼經過$even 解析後並不會將錯誤移交給 window.onerror 函數ajax
可是 angular 在解析時會將全部的語法、執行錯誤時將會觸發 $ExceptionHandlerProvider
函數:app
function $ExceptionHandlerProvider() { this.$get = ['$log', function($log) { return function(exception, cause) { $log.error.apply($log, arguments); }; }]; }
$ExceptionHandlerProvider
函數將會調用 consoleLog('error')
函數框架
this.$get = ['$window', function($window) { return { /** * @ngdoc method * @name $log#log * * @description * Write a log message */ log: consoleLog('log'), /** * @ngdoc method * @name $log#info * * @description * Write an information message */ info: consoleLog('info'), /** * @ngdoc method * @name $log#warn * * @description * Write a warning message */ warn: consoleLog('warn'), /** * @ngdoc method * @name $log#error * * @description * Write an error message */ error: consoleLog('error'), /** * @ngdoc method * @name $log#debug * * @description * Write a debug message */ debug: (function() { var fn = consoleLog('debug'); return function() { if (debug) { fn.apply(self, arguments); } }; }()) }; function consoleLog(type) { var console = $window.console || {}, logFn = console[type] || console.log || noop, hasApply = false; // Note: reading logFn.apply throws an error in IE11 in IE8 document mode. // The reason behind this is that console.log has type "object" in IE8... try { hasApply = !!logFn.apply; } catch (e) {} if (hasApply) { return function() { var args = []; forEach(arguments, function(arg) { args.push(formatError(arg)); }); return logFn.apply(console, args); }; } // we are IE which either doesn't have window.console => this is noop and we do nothing, // or we are IE where console.log doesn't have apply so we log at least first 2 args return function(arg1, arg2) { logFn(arg1, arg2 == null ? '' : arg2); }; }
最終這些錯誤會流入原生console.error內, 因此在angular下捕獲這些錯誤將變的異常簡單。僅僅須要重置console.error方法,以下所示:ide
resetConsole() { window.console._error = window.console.error; window.console.error = info => { // 在這裏執行錯誤存儲或發送 window.console._error(info); }; }
angular 在解析錯誤時, 會經過$log.error.apply $window.console.error方法. 因此在這裏將 console.error 進行重置後, 語法、執行錯誤也會一併收集到。函數
各框架都會將 XMLHttpRequest 進行封裝, 能夠找到對應的errror函數內將錯誤進行捕獲。oop
原生實現收集請求錯前, 須要先對XMLHttpRequest進行封裝,示例以下:
var ajax = function(type, url, callback){ var xhr = new XMLHttpRequest(); xhr.open(type, url); xhr.onreadystatechange = function() { if (xhr.readyState !== 4) { return; } if (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) { callback(); } else { console.log('收集到一條錯誤');// 在這裏收集錯誤信息 } }; xhr.send(null); } // 由於.ccccccom這個路徑是不存在的, 因此會執行收集區域的代碼。 ajax('GET', 'http://www.lovejavascript.ccccccom', function(a){console.log(a)});