13

我在頁面上有一個「新項目」徽章,我想立即更新頁面從緩存中加載(即當點擊「返回」或「轉發」返回此頁面時)。什麼是完成這個最好的方法?我的頁面是否從瀏覽器緩存加載?

設置非常簡單。該應用程序的佈局每8秒查找一次新項目,並相應地更新徽章+項目列表。

$(function() { 
    setInterval(App.pollForNewItems, 8000); 
}); 

當有人導航離開此頁面查看項目的詳細信息時,會發生很多事情。事情是「新」,直到任何用戶查看它們,並且該應用程序可能會有多個用戶同時使用它(用於呼叫中心或支持票的工作流類型)。

爲了確保徽章始終是最新的,我有:

$(window).bind('focus load', function (event) { 
    App.pollForNewItems(); 
}); 

..和雖然這工作,當頁面加載從投票上「負載」的新項目是唯一有用的緩存。是否有可靠的跨瀏覽器方式來判斷是否正在從緩存中加載頁面?

回答

6

部分解決方法是在服務器上設置當前時間的變量,並在當前頁面頂部的客戶端時間設置一個var。如果它們相差超過一定的閾值(1分鐘?),那麼你可以認爲它是一個緩存的頁面加載。

例JS(使用ASP.Net語法服務器端):

var serverTime = new Date('<%= DateTime.Now.ToUniversalTime().ToString() %>'); 
var pageStartTime = Date.UTC(new Date()); 
var isCached = serverTime < pageStartTime && 
       pageStartTime.getTime() - serverTime.getTime() > 60000; 

另外,使用在客戶端的cookie(假設已啓用了Cookie),您可以檢查一個cookie具有獨特的鍵爲當前版本的頁面。如果不存在,則爲它編寫一個cookie,並且在任何其他頁面訪問中,cookie的存在會向您顯示它正從緩存中加載。

E.g. (假設有一些cookie輔助函數可用)

var uniqueKey = '<%= SomeUniqueValueGenerator() %>'; 
var currentCookie = getCookie(uniqueKey); 
var isCached = currentCookie !== null; 
setCookie(uniqueKey); //cookies should be set to expire 
         //in some reasonable timeframe 
+1

我不會依賴服務器和客戶端進行特別好的同步:/ – Matchu 2010-12-13 21:50:15

+0

問題在於你假定時鐘同步。 JS中的時間取決於本地計算機的時間,這可能與服務器的時間有很大不同。 – Yahel 2010-12-13 21:50:35

+0

好點,我會更新使用UTC。 – jball 2010-12-13 21:55:11

0

就我個人而言,我會爲每個元素設置包含項目標識的數據屬性。

I.e.

<ul> 
    <li data-item-id="123">Some item.</li> 
    <li data-item-id="122">Some other item.</li> 
    <li data-item-id="121">Another one..</li> 
</ul> 

App.pollForNewItems功能會抓住的第一個元素的data-item-id屬性(如果最新的第一個),並將其與原始請求發送到服務器。

然後,服務器將只返回項目WHERE id > ...,然後您可以將它們預加到列表中。

我仍然困惑,爲什麼你想知道瀏覽器是否有緩存版本的頁面。

此外,是否有一個原因要約束到load而不是ready

  • 基督教
+0

基督徒,很好的建議,儘管應用程序已經做了什麼你描述了(儘管時間戳比較而不是ID)。至於使用'load'而不是'ready',我想也綁定到'focus'事件,並且我想讓我的代碼保持乾爽。 「就緒」是由jQuery構建的人爲事件,它只能綁定到文檔。如果您嘗試使用'$(document).bind('focus ready',{...})',處理程序將永遠不會針對'focus'事件觸發。由於從「緩存」加載的頁面的「就緒」和「加載」事件之間的時間差應該可以忽略不計,因此在這裏「加載」就好了。 – Blackcoat 2010-12-14 17:35:36

7

你可以向Web瀏覽器不緩存頁面。試試這些HTTP頭:

特別,Cache-control: no-store很有趣,因爲它告訴瀏覽器內存中的頁面不存儲在所有防止過時的頁面,當你點擊後退/前進按鈕加載。

如果你這樣做,你不必輪詢頁面加載數據。

+0

我甚至沒有想過緩存標題!只要性能沒有受到影響,這可能是正確的方法(我想確保它不會迫使UA始終下載應該跨應用程序緩存的共享資源,例如JS,CSS,圖像)。雖然這是解決這個問題的方法,但我仍然很好奇你是否可以檢測到頁面是否通過JS從緩存中加載。有什麼想法嗎? – Blackcoat 2010-12-14 17:37:04

+0

我不知道是否有方法可以判斷頁面是否來自緩存。不過,@ jball有正確的想法來檢測頁面呈現的日期。 – Jacob 2010-12-14 18:05:53

+0

在哪裏設置這些變量? – YakovL 2016-05-29 09:53:46

10

導航計時在大多數瀏覽器現在(IE9 +) http://www.w3.org/TR/navigation-timing/#sec-navigation-info-interface

if (!!window.performance && window.performance.navigation.type === 2) { 
    // page has been hit using back or forward buttons 
} else { 
    // regular page hit 
} 
+0

這個解決方案似乎不適用於Firefox? Firefox也有解決方法嗎? – Ralph 2016-04-10 09:47:33

+0

我的問題的最佳答案! – mgh 2016-04-13 13:24:42

0

請在您的js文件中嘗試以下腳本。

if(!!window.performance && window.performance.navigation.type == 2) 
{ 
    window.location.reload(); 
} 
相關問題