但error boundaries并不会捕捉以下错误:React事件处理,异步代码,error boundaries自己抛出的错误。
跨域问题
一般情况,如果出现 Script error 这样的错误,基本上可以确定是出现了跨域问题。
如果当前投放页面和云端JS所在不同域名,如果云端JS出现错误,window.onerror会出现Script Error。通过以下两种方法能给予解决。
<script src="http://yun.tuia.cn/test.js" crossorigin></script>
const script = document.createElement('script');
script.crossOrigin = 'anonymous';
script.src = 'http://yun.tuia.cn/test.js';
document.body.appendChild(script);
Test page <span style="color: rgb(198, 120, 221);line-height: 26px;">in</span> http://test.com
<body>
<script src="https://yun.dui88.com/tuia/cdn/remote/testerror.js"></script>
<script> window.onerror = function (message, url, line, column, error) {
console.log(message, url, line, column, error);
}
try {
foo(); // 调用testerror.js中定义的foo方法
} catch (e) {
throw e;
} </script>
会发现如果不加try catch,console.log就会打印script error。加上try catch就能捕获到。
我们捋一下场景,一般调用远端js,有下列三种常见情况。
调用方法场景
可以通过封装一个函数,能装饰原方法,使得其能被try/catch。
Test page <span style="color: rgb(198, 120, 221);line-height: 26px;">in</span> http://test.com
<body>
<script src="https://yun.dui88.com/tuia/cdn/remote/testerror.js"></script>
<script> window.onerror = function (message, url, line, column, error) {
console.log(message, url, line, column, error);
}
function wrapErrors(fn) {
// don't wrap function more than once
if (!fn.__wrapped__) {
fn.__wrapped__ = function () {
try {
return fn.apply(this, arguments);
} catch (e) {
throw e; // re-throw the error
}
};
}
return fn.__wrapped__;
}
wrapErrors(foo)() </script>
大家可以尝试去掉wrapErrors感受下。
事件场景
可以劫持原生方法。
Test page <span style="color: rgb(198, 120, 221);line-height: 26px;">in</span> http://test.com
<body>
<script> const originAddEventListener = EventTarget.prototype.addEventListener;
EventTarget.prototype.addEventListener = function (type, listener, options) {
const wrappedListener = function (...args) {
try {
return listener.apply(this, args);
}
catch (err) {
throw err;
}
}
return originAddEventListener.call(this, type, wrappedListener, options);
} </script>
"height: 9999px;">http://test.com