IE 中图片大小的误判

IE8 以下的浏览器都会出现这个问题,不致命,但非常影响页面观感。幸运的是,你不一定能遇上。

情景是,图片需要动态加载,根据给出的缩放比例调整显示大小。图片是普通 PNG,只是存放点是多样化的,同样的图片,一个以文件形式存在,另一个是保存于缓存(内存)中,前面都是用 Apache,一个读文件返回,一个做转发,用 IE 访问它们,获取其大小信息,结果竟然是不一样的。

装载图片的代码片段:

function loadImg(url, callback) {
    var img = new Image();
    img.src = url;
    
    if (img.complete) {
        console.log("complete");
        return callback.call(img, url);
    }
    img.onload = function() {
        img.onload = null;
        callback.call(img, url);
    }
    return img;
}

要完成缩放,需要获取图片的原始大小。当然也可以用百分比数值,方案比较不是本文重点。下面写一个函数可以打印出图像对象上所有的数值属性,当然包括宽和高。

function getParam() {
    var arr = [];
    for(var i in this) {
        try {
            if (typeof this[i] !== 'number') continue;
            arr.push(i + ' : ' + this[i] + '\n');
        } catch(e) {} // this[i] 在 IE 下有可能会报错,不影响观察,暂且忽略
    }
    alert(arr.join('')); // 使用 alert 方便观看结果
};

然后都执行下面的,其中 testPngURL 分别为两者的 URL,这也是唯一的区别了。

preload(testPngURL, getParam);

两次执行的结果显示的 width 和 height 是不一样的,而且不成比例,而且结果是可以稳定重复的。我最纳闷的是 IE 凭什么得出另外那个错误结果的。我初时觉得可能是两次请求的 header 不一样,主要差异是存放于内存的,其响应的 Content-Type 是 application/octet-stream,文件形式的则是 image/png,内容长度是完全一样的。于是我使用 Fiddler 对内存图像的请求进行拦截,并修改其 Content-Type,结果是无效的。甚至将两者的响应头弄成完全一致,也得不到一致的结果。

暂时还没想到有什么方法可以绕过。而且最奇怪的是,有少数几个 png 的大小是正确的。难道问题出在 png 的数据上,有些隐藏的信息,但触发点到底是什么,可是敲爆头也不知道了。

虽然生产不会这么使用,但为了开发调试方便,我们会使用缓存来存放各种资源,其返回头都是非常简单而且统一的,无任何多余 header,浏览器不会自作主张做缓存。更新也方便,往同一个地址 PUT 内容即可。现在由于 IE 存在这样一个问题,其显示大小是不正确的,非常影响观感,不得不需要做些调整了。

不应对 bug 有偏见

最近项目发展给我最大的感觉是,大家对 bug 抱有偏见。

出于项目管理与前期代码经营不足等原因,在版本发布临近之时,bug 猛增。其实 bug 多起来不是什么大问题,而且修复起来也挺快的,问题是为什么不能及早发现?直觉认为是测试在后期进行。但,提前让测试人员参与进来就能够解决问题吗?

在 bug 管理当中,是有分类的,人们对于不同种类的 bug 反应也是不一样的。例如对于一些 regression (倒退)表现得很严重。看似很合理的反应。

在某种程度上,开发的情绪是被测试牵引波动的。就像训练老鼠跑迷宫一样,电击多了就记得什么(错)路不能再走。但我怀疑这会不会导致开发会 LOST (迷失),忽略了代码中隐藏的各种信号,而依赖于测试反馈的信号。而据我观察,这种担忧不是多余,从开发修 bug 所改动的代码就可以看出。真是头痛医头,脚痛医脚,不报 bug,不修改。这里假设开发都不是应付式工作。这种对 bug 抱有偏见的状态所造成的问题,只要眼球足够多,迟早会以代码质量问题显现出来。那就是前一个现象发生的原因。

bug 不可怕,代码混乱才是问题,开发应该保持客观。显示 bug 是测试要做到事情,也是重要指标,但对于开发的,它也有指示作用,但肯定不是领头羊级的指标。开发要做的是书写良好的代码,让 bug 及早显现。不过也有一些外部因素,比如项目换血频繁,代码交接断裂,人员良莠不齐,普遍缺乏信托意识等等,都会造成累积的仅仅,仅仅是代码。

有良好的土壤,才能培育出丰厚的果实。