httpwatch引用swfobject的页面产生ERROR 0x57错误

2009-09-08 12:45:37

我用Swfobject嵌入SWF,用HTTPWatch抓抓包,竟然发现此问题! 原文 [url=http://blog.httpwatch.com/2007/11/20/error_internet_invalid_url-httpwatch/]http://blog.httpwatch.com/2007/11/20/error_internet_invalid_url-httpwatch/[/url] 一些用户反映,最近在他们的页面中通过 HttpWatch 抓包,有发现请求 http://:/ 这样的地址,想知道发生这种问题的原因。这样的 URL 会在 IE6 中显示 “ERROR 0x57”,而在 IE7 中显示为“ERROR_INTERNET_INVALID_URL”。 发生这样的错误都有一个共同的原因。他们一般都使用了 JQuery 或者 YUI 的 Javascript 库。很难立即发现是哪里生成了这个 URL,我们使用 IE Developer Toolbar 检查后发现,没有哪个 DOM 节点使用了这个 URL。 我们使用当前的 jQurey 库建立了一个简单的测试页。如果你使用 HttpWatch 抓包,你就能看见页面加载后,对 http://:/ 地址的请求被记录了下来。 [img]http://static2.photo.sina.com.cn/orignal/53d96fe3t63a479309067[/img] IE7 下抓图 [img]http://static2.photo.sina.com.cn/orignal/53d96fe3t63a479e68575[/img] IE6 下抓图 我们猜想会不会是 IE 自动加上了 http: 前缀和最后的反斜杠,于是,我们查找 //:。HttpWatch 高亮显示了 jquery.js 中的如下代码片段。它的作用是,在 IE 下做一个 Hack 来触发一个事件,效果等同于 Firefox 中 DOMContentLoaded 事件。 [img]http://static2.photo.sina.com.cn/orignal/53d96fe3t63a47879eb11[/img] jQuery 库不使用标准的 window.onload 事件,是因为该事件会等到页面和页面内的全部图片完全加载成功后才会被触发。如果图片较多,或者图片较大,会造成页面上的 JS 函数执行被严重地滞后。使用 DOMContentLoaded 事件的优点就在于,一旦页面的 Dom 节点完成后,JS 就可以安全的操作这些节点,而不会触发 IE 终止错误。 因此,在 IE 下创建了一个带有 defer 属性临时的 SCRIPT 标签,来产生一个与 DOMContentLoaded 事件相同作用的事件。(注:该 SCRIPT 标签的 onreadystatechanged 中可以监测 SCRIPT 的加载状态,如果 readyState 属性为 complete,就证明 DOM 节点已经完成并且可以操作。关于这种方法的可靠性,我们在另一篇文章中单独探讨)然而,如果 SCRIPT 标签有一个 defer 属性, SCRIPT 必须有一个 src 属性的时候才会触发 onreadystatechanged 事件。就是这里的 src 属性引起了这个错误的 URL 请求。 临时的 SCRIPT 标签会在事件触发后被删除,因此无法在页面的 DOM 节点中看到。 The temporary 相同的例子是使用 YUI 库: [img]http://static2.photo.sina.com.cn/orignal/53d96fe3t63a47aaab57e[/img] 如果你访问 YUI Event 示例,你仍然可以看到这个错误: [img]http://static2.photo.sina.com.cn/orignal/53d96fe3t705d3f8785cd[/img] SCRIPT 标签的 src 设置为 //: 是整个问题的根源。如果它是一个真实有效的 URL,必然导致一个冗余的网络请求。这个无效的URL 请求会在 HttpWatch 中显示为一个错误,但是会带来最小程度的性能开销。YUI Event 实例中我们可以看到,它仅仅增加了 3 毫秒的下载时间。