ImageVerifierCode 换一换
格式:DOCX , 页数:15 ,大小:22.27KB ,
资源ID:12087900      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/12087900.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(捕获页面中全局Javascript异常.docx)为本站会员(b****5)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

捕获页面中全局Javascript异常.docx

1、捕获页面中全局Javascript异常捕获页面中全局Javascript异常主题 UglifyJS一个流量巨大的前端页面面临的浏览器环境是非常复杂的,尤其是移动端页面(Android的碎片化所致)。面对如此多样的浏览器环境,常规的测试是无法完全覆盖的,我们需要一种页面脚本异常监控机制作为补充,保证能够发现前端页面脚本异常的原因。有很多种情况会导致Javascript抛出异常,包括网络失效、语法错误、运行时错误等。 我们希望在页面上有异常发生时,能够获得脚本错误的基本信息、文件url、行号 。接下来我们探讨几种实现方式。1 使用window.onError浏览器提供了全局的onError函数,我

2、们可以使用它搜集页面上的错误window.onerror = function(message, source, lineno, colno, error) . 其中mesage为异常基本信息,source为发生异常Javascript文件url,lineno为发生错误的行号,我们可以通过error.stack获取异常的堆栈信息。下面是chrome中通过window.onError捕获的错误例子:message: Uncaught ReferenceError: test is not definedsource: lineno: 16144colno: 6error: ReferenceEr

3、ror: test is not defined at at HTMLDocument. (这种方式看似完美,其实有一个致命的问题。有些浏览器为了安全方面的考虑,对于不同域的Javascript文件,通过window.onError无法获取有效的错误信息。比如firefox的错误消息只有 Script error ,而且无法获得确切的行号,更没有错误堆栈信息:message: Script error.source: lineno: 0colno: 0error: null为了使得浏览器针对window.onError的跨域保护失效, 我们可以在静态资源服务器或者CDN的HTTP头中加上如下允

4、许跨域提示:Access-Control-Allow-Origin: *并在引用Javascript脚本是加上crossorigin属性:完成上述两步后,我们就可以方便的使用window.onError进行全局异常捕获,并获取丰富的异常信息了。但是有时对于第三方的CDN,我们无法添加跨域相关的头信息,下面我们就讨论针这种情况的全局Javascript异常捕获方法。2 使用AST为所有函数加上try catch上文中提到了使用window.onError进行浏览器全局异常捕获,但是当我们无法添加跨域相关头信息时,window.onError就失效了。针对这种情况,我们可以对每一个函数添加try

5、catch来捕获函数内的异常,但是一个大型项目的函数太多,对每一个函数都手动添加try catch无疑是一个巨大的工作量。本文我们借助AST(抽象语法树)技术,对源文件进行预处理,对每个函数自动的添加try catch。语法树是对源代码最精确的表示,通过遍历和操作语法树,我们能够精确的控制源代码。生成JavaScript的AST是一件非常复杂的工作,本文暂时不打算涉及,好在UglifyJS已经有了完整的实现。比如如下代码:function test() var a = 1; var b = 2; console.log(a+b);可以用语法树表示:通过使用Uglify提供的操作AST(抽象语法

6、树)的API,我们可以对每个函数添加try catch代码块,并在catch中捕获该函数的一切异常,下面是我的实现(请参考我的github: try-catch-global.js ):var fs = require(fs);var _ = require(lodash);var UglifyJS = require(uglify-js);var isASTFunctionNode = function (node) return node instanceof UglifyJS.AST_Defun | node instanceof UglifyJS.AST_Function;var gl

7、obalFuncTryCatch = function (inputCode, errorHandler) if(!_.isFunction(errorHandler) throw errorHandler should be a valid function; var errorHandlerSource = errorHandler.toString(); var errorHandlerAST = UglifyJS.parse( + errorHandlerSource + )(error);); var tryCatchAST = UglifyJS.parse(trycatch(err

8、or); var inputAST = UglifyJS.parse(inputCode); var topFuncScope = ; /将错误处理函数包裹进入catch中 tryCatchAST.body0.bcatch.body0 = errorHandlerAST; /搜集所有函数 var walker = new UglifyJS.TreeWalker(function (node) if (isASTFunctionNode(node) topFuncScope.push(node); ); inputAST.walk(walker); /对函数进行变换, 添加try catch语句

9、 var transfer = new UglifyJS.TreeTransformer(null, function (node) if (isASTFunctionNode(node) & _.includes(topFuncScope, node) /函数内部代码搜集 var stream = UglifyJS.OutputStream(); for (var i = 0; i node.body.length; i+) node.bodyi.print(stream) var innerFuncCode = stream.toString(); /清除try catch中定义的多余语句

10、 tryCatchAST.body0.body.splice(0, tryCatchAST.body0.body.length); /用try catch包裹函数代码 var innerTyrCatchNode = UglifyJS.parse(innerFuncCode, toplevel: tryCatchAST.body0); /获取函数壳 node.body.splice(0, node.body.length); /生成有try catch的函数 return UglifyJS.parse(innerTyrCatchNode.print_to_string(), toplevel:

11、node); ); inputAST.transform(transfer); var outputCode = inputAST.print_to_string(beautify: true); return outputCode;module.exports.globalFuncTryCatch = globalFuncTryCatch;借助于 globalFuncTryCatch ,我们对每个函数进行自动化地添加try catch语句,并使用自定义的错误处理函数:globalFuncTryCatch(inputCode, function (error) /此处是异常处理代码,可以上报并

12、记录日志 console.log(error););通过将globalFuncTryCatch功能集成到构建工具中,我们就可以对目标Javascript文件进行try catch处理。综上所述:当静态资源服务器可以添加 Access-Control-Allow-Origin: * 时,我们可以直接使用window.onError进行全局异常捕获;当静态资源服务器不受控制,window.onError失效,我们可以借助AST技术,自动化地对全部目标Javascript函数添加try catch来捕获所有异常。参考文档:Capture and report JavaScript errors wi

13、th window.onerroronerror is a special browser event that fires whenever an uncaught JavaScript error has been thrown. Its one of the easiest ways to log client-side errors and report them to your servers. Its also one of the major mechanisms by which Sentrys client JavaScript integration (raven-js)

14、works.You listen to the onerror event by assigning a function to window.onerror:window.onerror = function (msg, url, lineNo, columnNo, error) / . handle error . return false;When an error is thrown, the following arguments are passed to the function:msg The message associated with the error, e.g. “U

15、ncaught ReferenceError: foo is not defined”url The URL of the script or document associated with the error, e.g. “/dist/app.js”lineNo The line number (if available)columnNo The column number (if available)error The Error object associated with this error (if available)The first four arguments tell y

16、ou in which script, line, and column the error occurred. The final argument, Error object, is perhaps the most valuable. Lets learn why.The Error object and error.stackAt first glance the Error object isnt very special. It contains 3 standardized properties: message, fileName, and lineNumber. Redund

17、ant values that already provided to you via window.onerror.The valuable part is a non-standard property: Error.prototype.stack. This stack property tells you at what source location each frame of the program was when the error occurred. The stack trace can be a critical part of debugging an error. A

18、nd despite being non-standard, this property is available in every modern browser.Heres an example of the Error objects stack property in Chrome 46:Error: foobarn at new bar (:241:11)n at foo (:245:5)n at :250:5n at :251:3n at :267:4n at callFunction (:229:33)n at :239:23n at :240:3n at Object.Injec

19、tedScript._evaluateOn (:875:140)n at Object.InjectedScript._evaluateAndWrap (:808:34)Hard to read, right? The stack property is actually just an unformatted string.Heres what it looks like formatted:Error: foobar at new bar (:241:11) at foo (:245:5) at callFunction (:229:33) at Object.InjectedScript

20、._evaluateOn (:875:140) at Object.InjectedScript._evaluateAndWrap (:808:34)Once its been formatted, its easy to see how the stack property can be critical in helping to debug an error.Theres just one snag: the stack property is non-standard, and its implementation differs among browsers. For example

21、, heres the same stack trace from Internet Explorer 11:Error: foobar at bar (Unknown script code:2:5) at foo (Unknown script code:6:5) at Anonymous function (Unknown script code:11:5) at Anonymous function (Unknown script code:10:2) at Anonymous function (Unknown script code:1:73)Not only is the for

22、mat of each frame different, the frames also have less detail. For example, Chrome identifies that the new keyword has been used, and has greater insight into eval invocations. And this is just IE 11 vs Chrome other browsers similar have varying formats and detail.Luckily, there are tools out there

23、that normalize stack properties so that it is consistent across browsers. For example, raven-js uses TraceKit to normalize error strings. Theres also stacktrace.js and a few other projects.Browser compatibilitywindow.onerror has been available in browsers for some time youll find it in browsers as o

24、ld as IE6 and Firefox 2.The problem is that every browser implements window.onerror differently. Particularly, in how many arguments are sent to to the onerror listener, and the structure of those arguments.Heres a table of which arguments are passed to onerror in most browsers:Browser Message URL l

25、ineNo colNo errorObjFirefox 42 Chrome 46 Android Browser 4.4 Edge IE 11 IE 10 IE 9, 8 Safari 9 iOS 9 Youll notice that the latest Apple browsers Safari and iOS dont support a 5th error object argument. And while the final version of Internet Explorer (11) supports the error object, Microsofts latest

26、 browser, Edge, does not.Without the error object, there is no stack trace property. This means that these browsers cannot retrieve valuable stack information from errors caught by onerror.Polyfilling window.onerror with try/catchBut there is a workaround you can wrap code in your application inside

27、 a try/catch and catch the error yourself. This error object will contain our coveted stack property in every modern browser.Consider the following helper method, invoke, which calls a function on an object with an array of arguments:function invoke(obj, method, args) return objmethod.apply(this, ar

28、gs);invoke(Math, max, 1, 2); / returns 2Heres invoke again, this time wrapped in try/catch, in order to capture any thrown error:function invoke(obj, method, args) try return objmethod.apply(this, args); catch (e) captureError(e); / report the error throw e; / re-throw the error invoke(Math, highest

29、, 1, 2); / throws error, no method Math.highestOf course, doing this manually everywhere is pretty cumbersome. You can make it easier by creating a generic wrapper utility function:function wrapErrors(fn) / dont wrap function more than once if (!fn._wrapped_) fn._wrapped_ = function () try return fn

30、.apply(this, arguments); catch (e) captureError(e); / report the error throw e; / re-throw the error ; return fn._wrapped_;var invoke = wrapErrors(function(obj, method, args) return objmethod.apply(this, args););invoke(Math, highest, 1, 2); / no method Math.highestBecause JavaScript is single threaded, you don

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1