// onerror
window.onerror = function(msg, url, row, col, error) {
// todo report
report({
msg: msg,
url: url,
row: row,
col: col
});
};
// onerror
window.onerror = function(msg, url, row, col, error) {
// get error stack
// Firefox and chrome support stack trace
var newMsg = error && error.stack ? _processStackMsg(error) : msg;
// todo report
report({
msg: newMsg,
url: url,
row: row,
col: col
});
};
// process error stack
var _processStackMsg = function(error) {
// error stack
var stack = error.stack.replace(/\n/gi, "")
.split(/\bat\b/).slice(0, 5).join("@").replace(/\?[^:]+/gi, "");
// error message
var msg = error.toString();
return stack.indexOf(msg) < 0 ? (msg + "@" + stack) : stack;
};
出现 “Script error” 的场景和条件:
1、通过 window.onerror 注册监听脚本错误事件
2、浏览器:Firefox、Chrome、Safari、IE7+(*)
3、页面内使用了 script 标签引入,非同域的资源, 且发生脚本错误。
举例:
http://ke.qq.com/index.html 里引用了
http://7.url.cn/index.js
本质上是出于安全考虑。因为 script 标签引入文件内容的时候是忽略文件本身的MIME声明,且是允许跨域请求的。这里如果不屏蔽掉跨域情况下的错误信息,很可能会给黑客提供一个攻击通道。
http://www.webryan.net/2012/12/something-about-window-onerror-script-error/
// http://trac.webkit.org/browser/trunk/Source/WebCore/dom/ScriptExecutionContext.cpp#L347
bool ScriptExecutionContext::sanitizeScriptError(
String& errorMessage,
int& lineNumber,
int& columnNumber,
String& sourceURL,
CachedScript* cachedScript
)
{
URL targetURL = completeURL(sourceURL);
if (securityOrigin()->canRequest(targetURL) ||
(cachedScript &&
cachedScript->passesAccessControlCheck(*securityOrigin())
)
)
return false;
errorMessage = "Script error.";
sourceURL = String();
lineNumber = 0;
columnNumber = 0;
return true;
}
在脚本文件的 HTTP response header 中设置 CORS
比如: Access-Control-Allow-Origin: http://ke.qq.com
在页面的 script 标签中设置 crossorigin 属性
比如: <script src="http://7.url.cn/index.js" crossorigin></script>
CORS header 和 crossorigin 取值问题
anonymous(默认)
CORS 不等于 origin, 不能带 cookie
CORS header 和 crossorigin 取值问题
use-credentials
CORS 不能设置为 *,能带 cookie
CORS 不等于 origin,js 直接不加载
Access-Control-Allow-Credentials: true
通过 XHR 获取脚本资源, 通过 script 标签 innerText 插入到页面
会丢失错误的行号列号和文件名等信息
资源加载切换到主域
会失去使用 CDN 的优势, 适合在排查问题的时候灰度一部分用户使用
使用 try catch
只需要对异步模块和业务主入口添加 try catch
<!-- 2.56 KB -->
<script src="/dist/bj-report.min.js"></script>
<!-- 或者 4.48 KB -->
<script src="/dist/bj-report-tryjs.min.js"></script>
BJ_REPORT.init({
id: 1 // 填写在管理后台申请的上报 id
});
BJ_REPORT.spyAll();