页首Html代码

让IE兼容console——“由于出现错误80020101而导致此项操作无法完成”的解决方案

问题描述

经测试发现问题只出现在:

1、原生IE8(其他版本IE模拟出的IE8无此问题)

2、从打开IE8没有开启过F12(曾经开启过又关闭的无此问题)

 

IE8报错“由于出现错误80020101而导致此项操作无法完成”,进而导致当前页面无法显示,同时整站所有页面都无法加载。

 

问题分析-IE8没有console对象

从上述症状分析,猜测应该跟IE8的开发者工具有关,说明代码中使用了IE开发者工具中提供的API接口或功能,而在没有开启F12时,因为没有相应接口导致报错。

 

通过开启F12发现输出了info信息,那就应该是代码中使用的console.info()导致的。

经检查发现IE8下当没有开启过F12时,window对象中没有console,遂使用console任何方法都会报错。

解决方案-IE下构造空console对象

增加兼容代码,若当前window中存在console对象则使用当前对象,不存在则新增window.console对象,将所有console函数定义为空函数。用以保证页面不会报错。 

新增兼容代码后,当IE8不能使用console时,也不会报错。美美的。

复制代码
//兼容IE8的空console对象
window.console = window.console || {
    log: $.noop,
    debug: $.noop,
    info: $.noop,
    warn: $.noop,
    exception: $.noop,
    assert: $.noop,
    dir: $.noop,
    dirxml: $.noop,
    trace: $.noop,
    group: $.noop,
    groupCollapsed: $.noop,
    groupEnd: $.noop,
    profile: $.noop,
    profileEnd: $.noop,
    count: $.noop,
    clear: $.noop,
    time: $.noop,
    timeEnd: $.noop,
    timeStamp: $.noop,
    table: $.noop,
    error: $.noop
};
复制代码

 

新问题-console对象不全

好景不长,没过多久测试组发现还有一些IE8版本报错,一看依然是console问题。

经测试发现,某些第三方库检测到了当前没有console对象,从而创建了一个畸形的console对象,遂骗过了上述兼容代码,但是它的console中只有log方法。而代码中使用了console.info,遂导致依然报错。

var str = "window.console:\n";
for (var i in window.console) {
    str += i + " : " + typeof (window.console[i]) + "\r\n";
}
alert(str);

 运行结果:

我总不能把代码改成检测console否含有info方法,天知道哪个库又兼容error方法但不兼容其他函数?

似乎解决方案只能重写console对象了

 

最终解决方案-重写console所有函数

将常用的console函数都重新包裹一遍,相当于hook原函数,内部判断是否可用。

 

复制代码
//兼容IE8的无console问题
window._console = window.console;//将原始console对象缓存
window.console = (function (orgConsole) {
    var consoleObj = {};//最终被替换的console对象
    var consoleFnArr = ["log", "debug", "info", "warn", "exception", "assert",
"dir", "dirxml", "trace","group", "groupCollapsed", "groupEnd", "profile",
"profileEnd", "count", "clear", "time", "timeEnd","timeStamp", "table",
"error", "memory", "markTimeline", "timeline", "timelineEnd"]; $.each(consoleFnArr, function (i, n) { consoleObj[n] = function actionConsole() { if (typeof (orgConsole) !== "object") return;//IE8不开控制台时console为undefined if (typeof (orgConsole[n]) === "function") {//调用标准浏览器内部console函数 return orgConsole[n].apply(orgConsole, Array.prototype.slice.call(arguments)); } else { //IE8下开启控制台时且console.log可用的情况下,执行typeof console.log返回"object"而不是"function" try { return orgConsole[n].apply(orgConsole, Array.prototype.slice.call(arguments)); } catch (ex) { return null; } } }; }); return consoleObj; }(window._console));
复制代码

 

关于上述代码中的try catch部分是因为:IE8下开启控制台时且console.log可用的情况下,执行typeof console.log返回"object"而不是"function"的BUG,具体可参照这篇文章

完美的解决了IE中的console对象不完整导致的各种问题,同时也不影响高级浏览器的console功能。

 

——2015年6月11日19:06:45

posted @   沧海月明FE  阅读(3775)  评论(1编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
点击右上角即可分享
微信分享提示