文章原发于个人主页:
https://www.bas369.com/more/learning_notes/2020/07/21/使用JavaScript记录cookie更新浏览器html缓存文件/

欢迎大家访问我的个人导航网站并且设置为主页:

巴士369,伴您到永久!https://www.bas369.com

1. 原理说明

1.利用浏览器响应 html 文件请求的响应头信息 last-modified (文件最后更新时间) 和 ETag 来判断 html 文件是否更新;
2.实际使用中,因为无法获取 ETag 信息,所以实际仅仅利用了请求头的 last-modified 信息;

2. 参考文档

  1. Web 开发技术请参见 HTTP请参见 HTTP HeadersLast-Modified:https://developer.mozilla.org...
  2. Web 开发技术请参见 HTTP请参见 HTTP HeadersETag:https://developer.mozilla.org...
  3. HTTP的请求头标签 If-Modified-Since:https://www.cnblogs.com/zh200...
  4. 你知道 http 响应头中的 ETag 是如何生成的吗:https://segmentfault.com/a/11...

3. 代码实现

// 本代码依赖于 jQuery ;
// jQuery(document).ready(function(){});  意义为在 DOM 加载完毕后执行了ready()方法,简写为 jQuery(function(){});  
$( document ).ready( function ( ) { 
    // 定义一个函数,用来记录 cookie ;
    function HomePageSetCookie_For_CheckHomePageHtmlFileIsChange_For_ReloadHomePageHtmlFile ( ) { 
        // 判断是否为网站的首页;
        if ( window.location.pathname == "/index.html" )  { 
            // 建立 xhr 请求;
            var xhr = new XMLHttpRequest();                                  
            if( !xhr ){  
                    xhr = new ActiveXObject("Microsoft.XMLHTTP");  
            }
            // 参数 HEAD 需要配合 nginx 的配置文件 if ($request_method !~* GET|POST|HEAD) { return 444; } ;否则无法获取回应;
            xhr.open( "HEAD" , window.location.href + "?timestamp=" + Date.now() , true ) ; 
            xhr.onreadystatechange=function(){  
                // xhr 请求成功;
                if( xhr.readyState == 4 && xhr.status == 200 ){  
                    // 定义函数,删除特殊字符串;
                    function DeleteTitle_SpecialString( LastModified ) {
                        LastModified = LastModified.replace(/\s+/g,'') ;  
                        LastModified = ( ( LastModified.replace( /,/g , '' ) ).replace( /;/g , '' ) ).replace( /:/g , '' ) ;  
                        return LastModified ;
                    }
                    // 提取 xhr 响应头的 last-modified ;
                    var ResponseHeaders_LastModified = xhr.getResponseHeader( "last-modified" ) ;
                          ResponseHeaders_LastModified = DeleteTitle_SpecialString( ResponseHeaders_LastModified ) ;
                    // 判断是否已经存在 cookie 记录,正则代码([^;]+)匹配非分号字符; (?:;|$)匹配分号或行尾 ;_HasIndexHtml 表示网站首页的 window.location.pathname 包含 "/index.html" 字符串 ;
                    if ( document.cookie.match(/HomePageSetCookie_ResponseHeaders_LastModified_HasIndexHtml=([^;]+)(;|$)/) != null ) {  
                        // 读取 cookie 记录;
                        var Array_LastModified_HasIndexHtml = document.cookie.match(/HomePageSetCookie_ResponseHeaders_LastModified_HasIndexHtml=([^;]+)(;|$)/); 
                        var Cookie_LastModified_HasIndexHtml = Array_LastModified_HasIndexHtml[ 0 ].substring( Array_LastModified_HasIndexHtml[ 0 ].indexOf( "=" ) + 1 , Array_LastModified_HasIndexHtml[ 0 ].length ) ;
                              Cookie_LastModified_HasIndexHtml = DeleteTitle_SpecialString( Cookie_LastModified_HasIndexHtml ) ;
                        // 根据 last-modified 判断 html 文件已经修改;
                        if ( Cookie_LastModified_HasIndexHtml != ( ResponseHeaders_LastModified + "_HasIndexHtml" ) ) {
                                // 更新 cookie 记录;
                                var cookie_path = "/" ; 
                                document.cookie = "HomePageSetCookie_ResponseHeaders_LastModified_HasIndexHtml="+ResponseHeaders_LastModified+"_HasIndexHtml; expires=Fri, 31 Dec 9999 23:59:59 GMT; " + ( window.location.host == "" ? "" : "domain=" + ( ( window.location.hostname ).indexOf( "www." ) != -1 ? ( window.location.hostname ).substring( 3 , ( window.location.hostname ).length ) : "." + window.location.hostname ) ) + "; path=" + cookie_path + "; SameSite=none; Secure=true" ; 
                                // 刷新网站的首页,更新 html 文件缓存;注意:要先更新 cookie 记录,后执行 window.location.reload( );  否则会导致页面刷新的死循环 ;
                                window.location.reload( ); 
                                // 重新赋值 variable_For_MultiTabPageHtmlReLoad_HasIndexHtml 变量;
                                // 用于浏览器同时打开多个标签页流量网站首页的时候,更新全部标签页的 html 文件缓存;
                                window.variable_For_MultiTabPageHtmlReLoad_HasIndexHtml = document.cookie.match(/HomePageSetCookie_ResponseHeaders_LastModified_HasIndexHtml=([^;]+)(;|$)/); 
                                window.variable_For_MultiTabPageHtmlReLoad_HasIndexHtml = window.variable_For_MultiTabPageHtmlReLoad_HasIndexHtml[ 0 ].substring( window.variable_For_MultiTabPageHtmlReLoad_HasIndexHtml[ 0 ].indexOf( "=" ) + 1 , window.variable_For_MultiTabPageHtmlReLoad_HasIndexHtml[ 0 ].length ) ;
                                window.variable_For_MultiTabPageHtmlReLoad_HasIndexHtml = DeleteTitle_SpecialString( window.variable_For_MultiTabPageHtmlReLoad_HasIndexHtml ) ;
                        }
                        else { // if ( Cookie_LastModified_HasIndexHtml == ( ResponseHeaders_LastModified + "_HasIndexHtml" ) ) {
                            // 更新 cookie 记录;
                            var cookie_path = "/" ;  
                            document.cookie = "HomePageSetCookie_ResponseHeaders_LastModified_HasIndexHtml="+ResponseHeaders_LastModified+"_HasIndexHtml; expires=Fri, 31 Dec 9999 23:59:59 GMT; " + ( window.location.host == "" ? "" : "domain=" + ( ( window.location.hostname ).indexOf( "www." ) != -1 ? ( window.location.hostname ).substring( 3 , ( window.location.hostname ).length ) : "." + window.location.hostname ) ) + "; path=" + cookie_path + "; SameSite=none; Secure=true" ;  
                            // 通过 variable_For_MultiTabPageHtmlReLoad_HasIndexHtml  变量,判断是否其他的标签页已经更新了 html 文件的同时,更新了 cookie  记录 ;
                            // 其他标签页虽然可以更新 cookie ,但是不能更新 本标签页的 window. 对象属性;
                            if ( $.type( window.variable_For_MultiTabPageHtmlReLoad_HasIndexHtml ) == "undefined" ) {
                                    // 定义一个变量,用来解决在 两个 标签页中 同时打开首页的时候:其中一个首页更新了 html 文件,并且重写了 cookie 记录;导致另外一个首页更新 html 文件失败的问题;
                                    // 因为第一个 首页更新 html 文件的时候,已经将 cookie 记录重写为最新的值,此时第二个标签页比对  ResponseHeaders_LastModified 与 cookie 记录,发现是相同的,就不会去更新 html 页面;
                                    // 此处定义一个变量就是为了解决此问题,先将 旧的 cookie 记录挂载到  window.  的全局变量上;
                                    // 如果发现  ResponseHeaders_LastModified 与 cookie 记录相同,那么就再比对最新的 cookie 记录(也就是最后的 ResponseHeaders_LastModified ) 与 全局变量  window.  上挂载的 cookie 旧记录是否相同;因为其他标签页虽然可以更新 cookie ,但是不能更新 本标签页的 window. 对象属性;
                                    // 不相同的话,说明其他的 html 文件已经更新了缓存,那么本标签页就重新载入 html 缓存文件;
                                    var variable_For_MultiTabPageHtmlReLoad_HasIndexHtml = document.cookie.match(/HomePageSetCookie_ResponseHeaders_LastModified_HasIndexHtml=([^;]+)(;|$)/); 
                                          variable_For_MultiTabPageHtmlReLoad_HasIndexHtml = variable_For_MultiTabPageHtmlReLoad_HasIndexHtml[ 0 ].substring( variable_For_MultiTabPageHtmlReLoad_HasIndexHtml[ 0 ].indexOf( "=" ) + 1 , variable_For_MultiTabPageHtmlReLoad_HasIndexHtml[ 0 ].length ) ;
                                          variable_For_MultiTabPageHtmlReLoad_HasIndexHtml = DeleteTitle_SpecialString( variable_For_MultiTabPageHtmlReLoad_HasIndexHtml ) ;
                                    window.variable_For_MultiTabPageHtmlReLoad_HasIndexHtml = variable_For_MultiTabPageHtmlReLoad_HasIndexHtml ;
                            }
                            else if ( window.variable_For_MultiTabPageHtmlReLoad_HasIndexHtml != ( ResponseHeaders_LastModified + "_HasIndexHtml" ) ) {
                                    // 刷新网站的首页,更新 html 文件缓存;
                                    window.location.reload( );
                                    // 重新赋值 variable_For_MultiTabPageHtmlReLoad_HasIndexHtml 变量;
                                    window.variable_For_MultiTabPageHtmlReLoad_HasIndexHtml = document.cookie.match(/HomePageSetCookie_ResponseHeaders_LastModified_HasIndexHtml=([^;]+)(;|$)/); 
                                    window.variable_For_MultiTabPageHtmlReLoad_HasIndexHtml = window.variable_For_MultiTabPageHtmlReLoad_HasIndexHtml[ 0 ].substring( window.variable_For_MultiTabPageHtmlReLoad_HasIndexHtml[ 0 ].indexOf( "=" ) + 1 , window.variable_For_MultiTabPageHtmlReLoad_HasIndexHtml[ 0 ].length ) ;
                                    window.variable_For_MultiTabPageHtmlReLoad_HasIndexHtml = DeleteTitle_SpecialString( window.variable_For_MultiTabPageHtmlReLoad_HasIndexHtml ) ;
                            }
                        }
                    } 
                    else { // == null  ,没有 cookie 记录;
                            var cookie_path = "/" ; 
                            document.cookie = "HomePageSetCookie_ResponseHeaders_LastModified_HasIndexHtml="+ResponseHeaders_LastModified+"_HasIndexHtml; expires=Fri, 31 Dec 9999 23:59:59 GMT; " + ( window.location.host == "" ? "" : "domain=" + ( ( window.location.hostname ).indexOf( "www." ) != -1 ? ( window.location.hostname ).substring( 3 , ( window.location.hostname ).length ) : "." + window.location.hostname ) ) + "; path=" + cookie_path + "; SameSite=none; Secure=true" ;  
                            // 定义一个变量,用来解决在 两个 标签页中 同时打开首页的时候:其中一个首页更新了 html 文件,并且重写了 cookie 记录;导致另外一个首页更新 html 文件失败的问题;
                            // 因为第一个 首页更新 html 文件的时候,已经将 cookie 记录重写为最新的值,此时第二个标签页比对  ResponseHeaders_LastModified 与 cookie 记录,发现是相同的,就不会去更新 html 页面;
                            // 此处定义一个变量就是为了解决此问题,先将 旧的 cookie 记录挂载到  window.  的全局变量上;
                            // 如果发现  ResponseHeaders_LastModified 与 cookie 记录相同,那么就再比对最新的 cookie 记录(也就是最后的 ResponseHeaders_LastModified ) 与 全局变量  window.  上挂载的 cookie 旧记录是否相同;因为其他标签页虽然可以更新 cookie ,但是不能更新 本标签页的 window. 对象属性;
                            // 不相同的话,说明其他的 html 文件已经更新了缓存,那么本标签页就重新载入 html 缓存文件;
                            var variable_For_MultiTabPageHtmlReLoad_HasIndexHtml = document.cookie.match(/HomePageSetCookie_ResponseHeaders_LastModified_HasIndexHtml=([^;]+)(;|$)/); 
                                  variable_For_MultiTabPageHtmlReLoad_HasIndexHtml = variable_For_MultiTabPageHtmlReLoad_HasIndexHtml[ 0 ].substring( variable_For_MultiTabPageHtmlReLoad_HasIndexHtml[ 0 ].indexOf( "=" ) + 1 , variable_For_MultiTabPageHtmlReLoad_HasIndexHtml[ 0 ].length ) ;
                                  variable_For_MultiTabPageHtmlReLoad_HasIndexHtml = DeleteTitle_SpecialString( variable_For_MultiTabPageHtmlReLoad_HasIndexHtml ) ;
                            window.variable_For_MultiTabPageHtmlReLoad_HasIndexHtml = variable_For_MultiTabPageHtmlReLoad_HasIndexHtml ;
                    }
                }  //  if( xhr.readyState == 4 && xhr.status == 200 )  语句结束
            }  //  xhr.onreadystatechange=function()  结束
            xhr.send(null);  
        }
    }
    // 页面打开的时候,立即执行一次函数,判断是否更新 html 文件;
    setTimeout ( function ( ) {
        HomePageSetCookie_For_CheckHomePageHtmlFileIsChange_For_ReloadHomePageHtmlFile ( ) ; 
    } , 1 ) ;
    // 每隔 15 分钟,定时检查 html 文件是否需要更新缓存;
    setInterval ( function ( ) {
            HomePageSetCookie_For_CheckHomePageHtmlFileIsChange_For_ReloadHomePageHtmlFile ( ) ; 
    } , 900000 ) ; 
} ) ; // $(document).ready(function(){ 

hgjian
38 声望0 粉丝