title: js捕获404错误 tags:
- fundebug
- 404
- usecaptureargument
- errorEvent categories: 前端 date: 2017-06-25 18:18:53
最近使用fundebug,发现fundebug升级到了0.1.0,支持了
Fundebug的JavaScript监控插件更新至0.1.0,可以监控3种不同类型的前端BUG:JavaScript执行错误、资源加载错误、HTTP请求错误。
以前一直记得浏览器404是无法捕获的,这是什么黑魔法呢?
众所周知通过ajax是可以获得状态的,那么正常图片的加载出错等我们都是通过onError来加载。但是全局捕捉404貌似没听过,特别是js等。
之前因为考虑无法捕捉到404等错误还特别考虑了非覆盖发布。
那么fundebug通过什么思路实现的呢?
扒了一下源码:
发现两处区别:
- 使用的是addEventListener而不是onError
- 判断了t.message
而我们正常是通过window.onerror来捕捉错误并且直接使用异常的message。
参考
Jump to the appropriate set of steps from the list below:
If the load resulted in an error (for example a DNS error, or an HTTP 404 error)Executing the script block must just consist of firing a simple event named error at the element.
Firing a simple event named e means that a event with the name e, which does not bubble (except where otherwise stated) and is not cancelable (except where otherwise stated), and which uses the
Event
interface, must be created and at the given target.
通过Google发现确实存在此种方法捕获各种错误
To capture all
error
events on the page, you can use with theuseCapture
argument set totrue
. The reasonwindow.onerror
will not do this is because it uses the bubble event phase, and theerror
events you want to capture do not bubble.If you add the following script to your HTML before you load any external content, you should be able to capture all the
error
events, even when loading offline.
You can access the element that caused the error through
e.target
. For example, if you want to know what file did not load on animg
tag, you can usee.target.src
to get the URL that failed to load.
因此可以认为上文中加载失败可以触发event,但是必须要设置useCapture
argument为true。
通过断点调试发现当出现404错误时类型为ErrorEvent
对应的event确实是没有message的。
e.addEventListener && e.addEventListener("error", function(t) { if (!t.message) { var r, n = (r = t.target ? t.target : t.srcElement) && r.outerHTML; n && n.length > 200 && (n = n.slice(0, 200)); var a = { type: "resourceError", target: { outerHTML: n, src: r && r.src, tagName: r && r.tagName, id: r && r.id, className: r && r.className, name: r && r.name, type: r && r.type } }; if (a.target.src && e.XMLHttpRequest) { var u = new XMLHttpRequest; u.Fundebug = !0, u.open("OPTIONS", a.target.src), u.send(), u.onload = function(e) { 200 !== e.target.status && (a.target.status = e.target.status, a.target.statusText = e.target.statusText), f(a) } } } }, !0);复制代码
由此就可以捕获了加载错误。