因为返回的信息会当做脚本文件来执行辅助卡盟,一旦返回的脚本内容出错了,也是无法捕捉到错误的信息。
解决办法也不难,跟之前一样,在添加动态添加脚本的时候加上 crossOrigin,并且在后端配上相应的 CORS 字段即可.
const script = document.createElement('script');
script.crossOrigin = 'anonymous';
script.src = url;
document.body.appendChild(script);
读者可以通过 npm run jsonp 查看效果
知道原理之后你可能会觉得没什么,不就是给每个动态生成的脚本添加 crossOrigin 字段嘛,但是在实际工程中,你可能是面向很多库来编程,比如使用 jQuery,Seajs 或者 webpack 来异步加载脚本,许多库封装了异步加载脚本的能力,以 jQeury 为例你可能是这样来触发异步脚本。
$.ajax({
url: 'http://localhost:8081/data',
dataType: 'jsonp',
success: (data) => {
console.log(data);
}
})
假如这些库中没有提供 crossOrigin 的能力的话(jQuery jsonp 可能有,假装你不知道),那你只能去修改人家写的源代码了,所以我这里提供一个思路,就是去劫持 document.createElement,从根源上去为每个动态生成的脚本添加 crossOrigin 字段。
document.createElement = (function() {
const fn = document.createElement.bind(document);
return function(type) {
const result = fn(type);
if(type === 'script') {
result.crossOrigin = 'anonymous';
}
return result;
}
})();
window.onerror = function (msg, url, row, col, error) {
console.log('我知道错误了,也知道错误信息');
console.log({
msg, url, row, col, error
})
return true;
};
$.ajax({
url: 'http://localhost:8081/data',
dataType: 'jsonp',
success: (data) => {
console.log(data);
}
})
效果也是一样的,读者可以通过 npm run jsonpjq 来查看效果:
这样重写 createElement 理论上没什么问题,但是入侵了原本的代码,不保证一定不会出错,在工程上还是需要多尝试下看看再使用,可能存在兼容性上问题,如果你觉得会出现什么问题的话也欢迎留言讨论下。
关于 Script error 的问题就写到这里,如果你理解了上面的内容,基本上绝大部分的 Script error 都能迎刃而解。