我正在与https://github.com/sameer-shelavale/blitz-gmap-editor合作;文件test5.html
允许您放置标记,当您单击它时,您将获得一个表单来编辑其属性:
我开始添加一些额外的按钮,添加带预先填充数据的标记。然后,我点击它们以显示表单,我在表单中没有编辑任何内容,然后按取消。在此之后大约半秒到一秒,我进入浏览器控制台:
TypeError: a.url.substr is not a function util.js:202:114
我非常想摆脱这个错误(注意它不会出现在原始的test5.html
中)。
问题是 - 首先我不知道这个功能是什么或做了什么;我找到了Do we have a Uncompressed javascript Library for Google Maps API V3:
没有未压缩的库。根据已发布的文档访问所有API方法,因此不需要是未压缩的版本。
是的,没错 - 绝对不需要,当然!当然,谷歌不会对他们的财产施加牵引力 - 只是没有人需要知道发生了什么,因为不可能遇到一个不好的问题:)
无论如何,Firefox吐出的堆栈跟踪是:
rz.prototype.load http://maps.googleapis.com/maps-api-v3/api/js/26/17/util.js:202:114
qz.prototype.load http://maps.googleapis.com/maps-api-v3/api/js/26/17/util.js:201:427
_.yz.prototype.load http://maps.googleapis.com/maps-api-v3/api/js/26/17/util.js:204:224
dz.prototype.load http://maps.googleapis.com/maps-api-v3/api/js/26/17/util.js:200:287
cz.prototype.load http://maps.googleapis.com/maps-api-v3/api/js/26/17/util.js:199:133
SS http://maps.googleapis.com/maps-api-v3/api/js/26/17/marker.js:5:217
WS http://maps.googleapis.com/maps-api-v3/api/js/26/17/marker.js:7:482
XS http://maps.googleapis.com/maps-api-v3/api/js/26/17/marker.js:7:116
VS.prototype.Y http://maps.googleapis.com/maps-api-v3/api/js/26/17/marker.js:35:646
_.zf.prototype.L/a.F< http://maps.googleapis.com/maps/api/js:112:4221
...和Chromium输出:
util.js:202 Uncaught TypeError: a.url.substr is not a function
rz.load @ util.js:202
cz.load @ util.js:199
oz @ util.js:6
lz @ util.js:6
kz.load @ util.js:201
qz.load @ util.js:201
_.yz.load @ util.js:204
dz.load @ util.js:200
cz.load @ util.js:199
SS @ marker.js:5
WS @ marker.js:7
XS @ marker.js:7
VS.Y @ marker.js:35
(anonymous function) @ js?v=3.26&libraries=drawing,geometry:112
所以,显然错误发生在rz.prototype.load
,并由_.zf.prototype.L/a.F<
(anonymous function)
发起;从Firefox信息(... maps / api / js:112:4221),我为_.zf.prototype...
提取了这个:
...
_.zf.prototype.L=function(){
var a=this;
a.F||(
a.F=window.setTimeout(
function(){
a.F=void 0; // <=== column:4221 here at ;
a.Y()
}
,a.ql)
)
};
...
这适用于rz.prototype
(包含util.js:202:114
):
...
rz.prototype.load=function(a,b){
var c=this.la;
this.b&&"data:"!=a.url.substr(0,5)||(a=new _.ez(a.url)); // column 114 is right before a.url.substr..
return c.load(a,function(d){
!d&&_.m(a.crossOrigin)?c.load(new _.ez(a.url),b):b(d)
})
};
...
因此,调用者_.zf.prototype.L
函数执行setTimeout
,最终调用rz.prototype
,这解释了为什么只有在我按“取消”后一段时间过期后才会显示此错误。 / p>
但我的问题是 - 代码的其余部分是什么,可能会调用此_.zf.prototype.L
函数?我该怎么找到?如果_.zf.prototype.L
本身是通过setTimeout
调用的,它是否会“记住”原始调用者/调用堆栈,是否可以检索它以进行调试?或者,是否可以设置一个断点,每当一个名为_.zf.prototype.L
的函数即将被调用时它会中断?
我试着查看How to view JavaScript function calls as they occur(它没有关于如何进行函数调用跟踪的信息);然后找到https://javascriptweblog.wordpress.com/2010/06/01/a-tracer-utility-in-2kb/ - 使用这个库,我可以这样做:
tracer.traceAll(BlitzMap,true);
tracer.traceAll(BlitzMap.getMapObj(),true);
....但是它跟踪对象函数OK,地图obj有点奇怪(在页面加载时控制台中有3000+ tracing traceOff
个消息)虽然它似乎也跟踪了一些部分 - 但是,当我执行我的测试用例时,在按下“取消”后,我得到的是我的代码跟踪(不会崩溃),然后一秒钟过去,我得到上面的错误/堆栈跟踪而没有任何其他跟踪。 / p>
那么,如何调试这样的问题?
答案 0 :(得分:1)
好吧,我设法解决了这个问题 - 即使近距离投票声称问题“太宽泛”。
首先,如果来自API的“前端”javascript是:
<script src="http://maps.googleapis.com/maps/api/js?v=3.26&libraries=drawing,geometry" type="text/javascript"></script>
...然后将其下载到文件中:
wget "http://maps.googleapis.com/maps/api/js?v=3.26&libraries=drawing,geometry" -O gmapsapi.js
...并在HTML中使用此文件而不是在线文件:
<script src="gmapsapi.js" type="text/javascript"></script>
然后在Firefox中打开您的HTML文件,让它运行,然后在Firefox中执行:文件/保存页面/网页,完成。
这将在保存的页面文件夹中本地下载其他脚本,如util.js
等。
现在,打开HTML文件的已保存(作为网页,完整版)版本 - 它应该还将脚本的在线链接替换为下载的本地文件。
然后,从保存的文件夹中打开gmapsapi.js
,并将换行符引入_.zf.prototype.L
功能:
_.zf.prototype.L=function(){
var a=this;
a.F||(a.F=window.setTimeout(function(){a.F=void 0;a.Y()},a.ql))
};
...以后能够在一行上设置断点。
现在,在Firefox中打开已保存的HTML文件,打开Firebug,在“脚本”选项卡中找到gmapsapi.js
,并在var a=this;
行上设置断点。
现在运行这些东西 - 在我的情况下,完成所有操作并包括按下取消 - 并且JS引擎将会中断;然后你可以在Firebug控制台中做console.trace()
,并获得这种跟踪(之后发生错误):
_.zf.prototype.L() gmapsapi.js (line 114)
VS.prototype.changed(a="modelIcon") marker.js (line 35)
Bb(a=Object { type="object"}, b="modelIcon") gmapsapi.js (line 37)
Bb(a=Object { type="object"}, b="icon") gmapsapi.js (line 37)
_.k.set(a="icon", b=Object { type="object"}) gmapsapi.js (line 96)
_.vc/<(c=Object { type="object"}) gmapsapi.js (line 47)
_.k.setValues() gmapsapi.js (line 97)
a = Object { type="object"}
BlitzMap</this.updateOverlay() blitz.js (line 545)
BlitzMap</this.closeInfoWindow() blitz.js (line 514)
onclick()input[3] onclick (line 1)
event = Object { type="object"}
......确实 - 这指出了bug的位置:即,我已经攻击blitz.js
并最终为标记的图标写了一个空字符串""
,最终成为了错误的原因。
这个堆栈跟踪揭示了另外一件事 - 也就是说,为什么这个错误只在我第一次按取消时发生,而不是后续时间;好吧,答案是,错误的代码只在VS.prototype.changed(a="modelIcon")
时运行,所以第二次,空字符串的设置不再是“更改”,所以没有错误。