js获取Last-Modified Header的问题(document.lastModified)

这里不是关于像nodejs那样的服务端js,运行在页面中的js想直接获取http流中的Header是很困难的,出于安全的考虑也是不被允许的,

庆幸的是:还好各大浏览器都已经提供了对Last-Modified的支持,好像这是提供的唯一的Header,用js通过document.lastModified就能直接访问到。

悲剧的是:各大浏览器对读取这一Header的支持没有一个统一的规范,兼容性实在不敢恭维。

 

差异1

在服务端有发送 Last-Modified Header 的情况下,也就是Http流中包含有该Header时,不同浏览器的时间格式不一致,有UTC时间和LocalTimeZone之分:

UTC:IE,Firefox,Opera
LocalTimeZone:Chrome,Safari

 

差异2

当Http流中没有该Header时,我的第一反应是觉得应该返回null,可惜事与愿违,不同的浏览器返回的东西也有差别,有返回时间初始值和返回当前时间之分:

初始值:Opera

当前时间:Firefox、IE、Chrome、Safari

 

为了使用上的方便,需要包装掉这些差异,针对各个主要的浏览器实现一个统一的行为。

 

解决差异1,

可以通过改变Chrome、Safari的时间时区来解决。

 

解决差异2,

只要跟当前时间对比就可以了?。。。等等不是的,脚本被执行的时间是在页面完成载入的时间之后的,而这个时间差也是很难得到一个确切的值,因为假如判断的脚本是放在脚本文件的话,还要算上页面载入该脚本文件的网络请求的时间开销,就算是硬编码在页面的script标签内,理论也是有一个比较短暂的时间差的,所以这个时间差要自己拿捏好,我的代码中以30秒为时间差,个人觉得这在实际使用中完全可以,这是假设最坏的情况下该脚本在30秒内被执行,而在这30秒内的真实的Last-Modified会被忽略返回null,对一个正常运行的站点来说是不会出现30秒内的Last-Modified的资源的。

 

以下是代码:

    /*
    * browser
    */
    var ua = navigator.userAgent.toLowerCase(), check = function (r) { return r.test(ua); }, isOpera, isSafari;
    var browser = {
        chrome: check(/\bchrome\b/),
        opera: (isOpera = check(/opera/)),
        safari: (isSafari = check(/webkit/)),
        gecko: !isSafari && check(/gecko/),
        msie: !isOpera && check(/msie/)
    };
    /*
    * fix the 'lastModified' difference between major browsers
    */
    var lastModified = function (defer) {
        // when server does not send Last-Modified Header opera provide a minimum datetime value.
        var time = new Date(document.lastModified);
        if (time.getTime() === 0) { return null; }
        // assume that this script will be executed in 30 seconds after the clien page loaded.
        var now = new Date(), deferTicks = (defer || 30) * 1000;
        if (browser.chrome || browser.safari) {
            // chrome and safari use a LocalTime type
            var offset = -now.getTimezoneOffset(); // unit of minute
            time = new Date(time.getTime() + (offset * 60 * 1000));
        }
        if (now - time < deferTicks) { return null; }
        // ret
        return time.getTime();
    } ();

 

 

参考文档:

https://developer.mozilla.org/en/DOM/document.lastModified

 

 

 

posted on 2012-06-01 10:11  rulee  阅读(4700)  评论(0编辑  收藏  举报