如何在Chrome扩展内容脚本中获取错误堆栈跟踪
How to get errors stack trace in Chrome extension content script?
有一个带有content script
的Google Chrome扩展,可以处理所有选项卡页面上发生的JS错误。但问题是,获取错误堆栈跟踪的常用方法都不起作用。
例如,Chrome扩展的content script
中有一个代码:
window.addEventListener('error', function(event) {
console.log(event.error.stack); // event.error will be null
}, false);
如果我在网页内调用此代码,那么event.error
将包含具有stack
属性的Error
对象。
尝试使用获取堆栈跟踪的问题相同
console.log((new Error()).stack));
有人知道在Chrome扩展的content script
中获取错误堆栈跟踪的一些工作问题吗?
错误堆栈跟踪必须以string
或Array
的形式接收,这意味着不只是像JS控制台中通过调用console.trace()
的某些输出一样。
如何复制:
- 下载https://mega.co.nz/#!ENw00YAC!92gBZEoLCO9jPsWyKht4dbjYyo0Zk-PU5YAj0h88-3Q
- 将
jzen.zip
解压缩到某个/jsen
文件夹 - 在Google Chrome中打开
chrome://extensions
,启用Developer mode
https://i.stack.imgur.com/OLwpa.png - 单击
Load unpacked extension
按钮并选择指向/jsen
文件夹的路径 - 打开
/jsen/content.js
文件,在window.addEventListener('error', function(e) {
中添加console.log('JSEN', e.error.stack);
- 转到http://xpart.ru/_share/js.htm并在JS控制台中查看结果(Ctrl+Shift+J)
- 尝试编辑
/jsen/content.js
以获得正确的错误跟踪 - 要重新初始化Chrome扩展源代码,请单击https://i.stack.imgur.com/2LIEa.png
如前所述,在Content Script上下文中捕获事件时,事件对象的error
属性为null
,但在网页上下文中捕获时具有所需信息。因此,解决方案是在网页上下文中捕获事件,并使用消息传递将其传递到内容脚本。
// This code will be injected to run in webpage context
function codeToInject() {
window.addEventListener('error', function(e) {
var error = {
stack: e.error.stack
// Add here any other properties you need, like e.filename, etc...
};
document.dispatchEvent(new CustomEvent('ReportError', {detail:error}));
});
}
document.addEventListener('ReportError', function(e) {
console.log('CONTENT SCRIPT', e.detail.stack);
});
//Inject code
var script = document.createElement('script');
script.textContent = '(' + codeToInject + '())';
(document.head||document.documentElement).appendChild(script);
script.parentNode.removeChild(script);
所使用的技术如所述:
- https://stackoverflow.com/a/9517879/1507998
- https://stackoverflow.com/a/9636008/1507998
问题
主要问题是JS上下文隔离,即"内容脚本在一个称为隔离世界的特殊环境中执行"当然,这是一件好事,因为它避免了冲突并增强了安全性,但如果你想捕捉错误,这也是一个问题。
每个孤立的世界都可以看到自己版本的(窗口)对象。指定给对象会影响对象的独立副本。。。
两者都不能读取另一方的事件处理程序。事件处理程序是按照分配它们的顺序调用的。
解决方案
可能的解决方案(也称为破解)包括以下步骤:
- 向网页本身注入一些代码(并尽量使其不突兀,以避免冲突)
- 在该代码中,为错误注册一个事件侦听器,并将错误数据存储在DOM节点的数据集中
- 最后,在内容脚本中,使用MutationObserver来观察该DOM节点属性的变化
- 一旦指定数据发生更改-<…>属性被检测到,获取它的新值,您就可以在内容脚本中获得错误信息:)
源代码
下面是一个示例扩展的源代码。
manifest.json:
{
"manifest_version": 2,
"name": "Test Extension",
"version": "0.0",
"content_scripts": [{
"matches": ["*://*/*"],
"js": ["content.js"],
"run_at": "document_start",
"all_frames": true
}],
}
content.js:
/* This <script> element will function as an "error-proxy"
* for the content-script */
var errorProxy = document.createElement('script');
errorProxy.id = 'myErrorProxyScriptID';
errorProxy.dataset.lastError = '';
/* Make the content as non-obtrusive as possible */
errorProxy.textContent = [
'',
'(function() {',
' var script = document.querySelector("script#' + errorProxy.id + '");',
' window.addEventListener("error", function(evt) {',
' script.dataset.lastError = evt.error.stack;',
' }, true);',
'})();',
''].join(''n');
/* Add the <script> element to the DOM */
document.documentElement.appendChild(errorProxy);
/* Create an observer for `errorProxy`'s attributes
* (the `data-last-error` attribute is of interest) */
var errorObserver = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
if ((mutation.type === 'attributes')
&& (mutation.attributeName === 'data-last-error')) {
console.log('Content script detected new error:'n',
errorProxy.dataset.lastError);
}
});
});
errorObserver.observe(errorProxy, { attributes: true });
相关文章:
- chrome在WebSocket握手期间获取新错误
- 在引用最新的rxjs时获取rxjs错误
- Ruby on Rails屏幕抓取错误-“;您必须在浏览器中启用javascript才能使用此应用程序"
- Twitter引导程序弹出在网站上不起作用:未获取引用错误
- 正在获取语法错误:意外的标识符和未捕获的ReferenceError
- D3 Json请求获取XmlHttpRequest错误:访问控制允许原点不允许原点为null
- 使用.content().get().nodevalue;后在firebug中获取类型错误;
- 使用hasAttribute()获取类型错误:hasAttribute不是函数
- jquery日期分析器错误获取NaN错误
- 在jquery ajax POST中获取400(错误请求)错误
- 无法在 IE 10 中获取属性错误
- jQuery 在使用 ajax 时抓取错误的形式
- 获取类型错误:无法在 angularjs 控制器中调用未定义的方法 'then'
- 未定义获取 jquery 错误 $
- AngularJS在从HTTP返回的JSON中获取语法错误.JSONP.
- 在使用日历的产品页面上的 magento 中获取“类型错误:触发器元素为空”错误
- 调用函数时获取类型错误
- 无法在节点应用程序上获取/文件名错误
- JavaScript 中的 try-catch:如何获取原始错误的堆栈跟踪或行号
- 需要获取 JavaScript 错误对象