這里不是關於像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