zoukankan      html  css  js  c++  java
  • js获取LastModified 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

    浏览器没那么聪明!
  • 相关阅读:
    封装/接口/抽象类
    继承
    浅谈面向对象
    MySQL---Mybatis 批处理(增,改,删)
    dashboard安装
    K8S--------常用命令
    K8S------概述
    Java实现 MD5加盐加密 和 MD5和SHA-1混合加盐加密
    使用FastJson对JSON字符串、JSON对象及JavaBean之间的相互转换
    SpringCloud---FeignClient处理请求超时问题
  • 原文地址:https://www.cnblogs.com/rulee/p/2529893.html
Copyright © 2011-2022 走看看