最近从用户那里收到反馈说访问产品出现“白屏”,
由于版本上线前都必须在众多不同环境下通过测试,
于是猜想这个问题的出现与用户的浏览器设置有关;
进而联系用户来模拟其使用环境加以调试,
终于定位并解决了这个“非主流” Bug ,
记录如下以供各位参考。

这里先描述一下重现场景
必须同时满足如下所有条件:

  • IE 6;
  • 启用了“代理自动配置 PAC “;
  • 页面内容非空且使用 http 协议访问;
  • 页面引用了一个未经缓存的外部脚本;
  • 该脚本问了 location 对象;

该场景下访问页面会得到 Access Denied 错误(捕获错误后如下图),
出错位置正是访问 location 对象的那一句。

访问 location 对象时报错

测试环境只对 IE 6 启用了 PAC 而已,
其它设置均保持默认值,
所以除了说服用户升级浏览器或放弃使用 PAC 之外,
我们只能想办法去规避这个问题。<!--more-->

幸亏 document 对象下还挂着个 URL 属性,
它指向文档的实际地址,
且在绝大部分情况下等同于 location.href
因此我们只需要用正则利用 DOM 对象去分解它即可,
例如:

document.URL.match(/^([^:]+):\/\/(?:([^:@]+):?([^@]*)@)?(?:([^/?#:]+):?(\d*))([^?#]*)(?:\?([^#]+))?(?:#(.+))?$/);

当然,定位问题的过程不复杂却很繁琐:
首先当然是去微软知识库搜索,
找到两个可能相关的:KB 908356KB 884430
提到了安全区域设置,

于是怀疑与 PAC 文件所使用的协议或域名有关——
PAC 、外链脚本和文档统一为同域,报错;
改用 file: 协议来访问 PAC 文件,果然正常了;
将外链脚本改为内联书写,也正常

既然只在脚本外链时才出现,
想试试是否跟文档状态和写法有关呢?
调整外链脚本的加载和访问 location 对象的时机
(head/body/异步/domReady/load/延时等……),仍旧报错;

我也曾怀疑是否和 PAC 的写法有关,
突发奇想将 PAC 文件内容清空,结果<span style="color: #008000;">世界清静了</span>;
但只要加上一个字节,
(哪怕没有 PAC 所需的 FindProxyForURL() 函数定义)
你终归是无权访问 location 对象的。

不止是原生 IE 6 ,
IETester 内置的 IE 6 引擎也可以重现问题,
但 5.5 反而不会(抱歉并未用原生 5.5 测试);

最后,虽然重现条件看似很苛刻,
但只要用户使用 IE6 并配置了 PAC
(反馈该问题的用户浏览器便被某播客加速软件自动启用了 PAC 文件),
要想满足“外链文件未缓存”和“访问 location 对象”这两个条件还是挺容易的。
所以如果你的产品功能需要从文档 URL 取信息,
那么可以考虑予以改进。

P.S.
由于 Fiddler 的原理是接管浏览器代理,
所以如需抓包调试,
要么将 127.0.0.1:8888 写入 PAC 文件,
要么使用网卡抓包工具等其它方案。

如果找到相关资料欢迎留言告知,
这里为懒人们提供一个最简的测试用例

标签: Bugfix, IE

添加新评论