介绍完背景后,那么我们应该去解决这个问题?
首先可以想到的方案肯定是同源化策略,将 JS 文件内联到 html 或者放到同域下,虽然能简单有效地解决 script error 问题,但是这样无法利用好文件缓存和 CDN 的优势,不推荐使用。正确的方法应该是从根本上解决 script error 的错误。
跨源资源共享机制( CORS )
首先为页面上的 script 标签添加 crossOrigin 属性
// http://localhost:8080/index.html
<script>
window.onerror = function (msg, url, row, col, error) {
console.log('我知道错误了,也知道错误信息');
console.log({
msg, url, row, col, error
})
return true;
};
script>
<script src="http://localhost:8081/test.js" crossorigin>script>
// http://localhost:8081/test.js
setTimeout(() => {
console.log(error);
});
当你修改完前端代码后,你还需要额外给后端在响应头里加上 Access-Control-Allow-Origin: localhost:8080,这里我以 Koa 为例。
const Koa = require('koa');
const path = require('path');
const cors = require('koa-cors');
const app = new Koa();
app.use(cors());
app.use(require('koa-static')(path.resolve(__dirname, './public')));
app.listen(8081, () => {
console.log('koa app listening at 8081')
});
读者可通过 npm run cors 详细的跨域知识我就不展开了,有兴趣可以看看我之前写的文章:跨域,你需要知道的全在这里
你以为这样就完了吗?并没有,下面就说一些 Script error 你不常遇见的点:
我们都知道 JSONP 是用来跨域获取数据的,并且兼容性良好,在一些应用中仍然会使用到,所以你的项目中可能会用这样的代码:
// http://localhost:8080/index.html
window.onerror = function (msg, url, row, col, error) {
console.log('我知道错误了,但不知道错误信息');
console.log({
msg, url, row, col, error
})
return true;
};
function jsonpCallback(data) {
console.log(data);
}
const url = 'http://localhost:8081/data?callback=jsonpCallback';
const script = document.createElement('script');
script.src = url;
document.body.appendChild(script);