假设我们有一个函数,它会生成一个错误抛出函数:
function p(){
function q(){
throw new Error();
}
q();
}
p();
堆栈跟踪看起来像这样:
Error: x
at path:3:8
at q (path:5:4)
at p (path:7:1)
然后p
函数看起来像这样:
如何更改p
以获得如下所示的堆栈跟踪?
Error: x
at something-else:12:12
at q (something-else:34:34)
at p (path:7:1)
我无法控制文件,因为通过客户端代码我们现在使用捆绑包,因此将q
放入单独的文件中不是解决方案。据我所知,我的要求是不可能的,但也许有人比我更了解js。 :d
如果您想知道这里的目标是什么,我想教一下路径在帧字符串中的堆栈解析器。
答案 0 :(得分:0)
我找到了多种方法:
我从一种数据URI方法开始,这种方法并不广泛支持,但仍然不过是:
function report(e){
console.log(e.stack);
}
window.onload = function (){
var s = document.createElement("script");
s.setAttribute("src", "data:text/html,try {throw new Error;}catch(e){report(e);}");
var body = document.getElementsByTagName("body")[0];
body.appendChild(s);
}
它适用于最近的主要桌面浏览器,IE除外,它不允许脚本标记的数据URI。它记录以下堆栈:
Error
at data:text/html,try {throw new Error;}catch(e){report(e);}:1:12
之后我想到了它并且我认为如果这适用于数据URI,那么它也可能适用于iframe,所以我提出了这个:
function report(e){
console.log(e.stack);
}
window.onload = function (){
var i = document.createElement("iframe");
i.setAttribute("style", "display:none");
var body = document.getElementsByTagName("body")[0];
body.appendChild(i);
var idoc = i.contentDocument || i.contentWindow.document;
var ibody = idoc.getElementsByTagName("body")[0];
var s = document.createElement("script");
s.innerHTML="try {throw new Error;}catch(e){parent.report(e);}";
ibody.appendChild(s);
}
它记录以下堆栈:
FF:
@about:blank:1:12
window.onload@file:///C:/Users/inf3rno/Downloads/x.html:18:2
Chrome和Opera:
Error
at <anonymous>:1:12
IE11
Error
at Global code (Unknown script code:1:6)
at window.onload (file:///C:/Users/inf3rno/Downloads/x.html:17:2)
我们可以通过添加函数调用来添加另一个框架:
s.innerHTML="function a(){\ntry {\nthrow new Error;\n}catch(e){\nparent.report(e);\n}\n};\n a();";
在IE中记录以下内容:
Error
at a (Unknown script code:3:1)
at Global code (Unknown script code:8:2)
at window.onload (file:///C:/Users/inf3rno/Downloads/x.html:19:2)
因此我们可以将at a (Unknown script code:3:1)
与父窗口中调用的类似函数进行比较:at a (file:///C:/Users/inf3rno/Downloads/x.html:13:1)
并且找到路径相对容易。
使用eval是一种有趣的方法。它在IE中提供类似at a (eval code:3:1)
的内容,而在其他浏览器和节点中,它提供了一个复杂的嵌套位置:at a (eval at window.onload (x.html:21), <anonymous>:3:7)
或at a (eval at <anonymous> (repl:1:1), <anonymous>:1:20)
。我认为这是最好的方法,因为它不需要DOM,即使在严格模式下也可以在每个js环境中使用。