2012-10-25 79 views
9

我正在開發一個使用GWT的web應用程序,並且在瀏覽器中看到一個與app.nocache.js文件緩存的瘋狂問題,即使Web服務器發送了該文件的新副本!如何使瀏覽器停止緩存GWT nocache.js

我正在使用Eclipse編譯應用程序,該應用程序在開發模式下工作。爲了測試生產模式,我有一臺虛擬機(Oracle VirtualBox),在我的主機上運行Ubuntu guest OS(Windows 7)。我在VM中運行lighttpd web服務器。 VM正在共享我的項目的戰爭目錄,並且Web服務器正在爲此目錄服務。

我使用Chrome作爲瀏覽器,但同樣的事情發生在Firefox中。

這裏的情景:

  • 該網頁的應用程序是空白。對Chrome的「檢測元素」工具表示贊同,這是因爲它試圖獲取6E89D5C912DD8F3F806083C8AA626B83.cache.html,這不存在(404 not found)。
  • 我檢查戰爭目錄,果然,該文件不存在。
  • 瀏覽器上的app.nocache.jsWAS RELOADED來自Web服務器(200 OK),因爲服務器上的文件比瀏覽器緩存更新。我確認了服務器返回的新文件的文件大小和時間戳是正確的。 (這是關於服務器的HTTP響應的Chrome報告)
  • 但是,如果我在瀏覽器上打開app.nocache.js,則javascript指的是6E89D5C912DD8F3F806083C8AA626B83.cache.html!也就是說,即使網絡服務器發送了一個新的app.nocache.js,瀏覽器似乎已經忽略了這一點,並繼續使用它的緩存副本!

  • 轉到Google-> GWT在Eclipse中編譯。重新編譯整個事情。

  • 在戰爭目錄中驗證app.nocache.js已被覆蓋並具有新的時間戳。
  • 從Chrome重新加載頁面,並再次驗證服務器向app.nocache.js發送了200 OK響應。
  • 瀏覽器再次嘗試加載6E89D5C912DD8F3F806083C8AA626B83.cache.html並失敗。瀏覽器仍在使用舊版緩存副本app.nocache.js
  • 製造絕對肯定的戰爭目錄中,沒有什麼是指6E89D5C912DD8F3F806083C8AA626B83.cache.html(通過查找和grep)

到底哪裏出問題了?爲什麼瀏覽器緩存這個nocache.js文件,即使服務器正在發送一個新的副本?


這是在瀏覽器中單擊重新加載時HTTP請求/響應標頭的副本。在此跟蹤,服務器的內容還沒有被最後得到重新編譯(但要注意nocache.js的緩存版本仍然是錯的!):

Request URL:http://192.168.2.4/xbts_ui/xbts_ui.nocache.js 
Request Method:GET 
Status Code:304 Not Modified 
Request Headersview source 
Accept:*/* 
Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3 
Accept-Encoding:gzip,deflate,sdch 
Accept-Language:en-US,en;q=0.8 
Cache-Control:max-age=0 
Connection:keep-alive 
Host:192.168.2.4 
If-Modified-Since:Thu, 25 Oct 2012 17:55:26 GMT 
If-None-Match:"2881105249" 
Referer:http://192.168.2.4/XBTS_ui.html 
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.94 Safari/537.4 
Response Headersview source 
Accept-Ranges:bytes 
Content-Type:text/javascript 
Date:Thu, 25 Oct 2012 20:27:55 GMT 
ETag:"2881105249" 
Last-Modified:Thu, 25 Oct 2012 17:55:26 GMT 
Server:lighttpd/1.4.31 
+0

順便說一句,這看起來類似於http://stackoverflow.com/questions/3407649/stop-browser-scripts-caching-in-gwt-app,但它沒有包含任何幫助我解決這個問題的信息。 – jfritz42

+0

您是否閱讀過https://developers.google.com/web-toolkit/doc/latest/DevGuideCompilingAndDebugging#perfect_caching? –

+0

是的,似乎正確的事情正在發生,因爲該頁面顯示「If-Modified-Since fetch足夠」。我可以從Chrome Inspect Element工具中得知,瀏覽器在GET請求中發送了「If-Modified-Since:Thu,2012年10月25日17時03分53秒」,服務器以「Last-Modified:Thu,25 2012年10月17:55:26 GMT「 – jfritz42

回答

5

避免瀏覽器緩存的最佳方法是將到期時間設置爲現在並添加max-age = 0和必須重新驗證的控件。

這是我的配置與Apache的httpd使用

ExpiresActive on 
<LocationMatch "nocache"> 
    ExpiresDefault "now" 
    Header set Cache-Control "public, max-age=0, must-revalidate" 
</LocationMatch> 
<LocationMatch "\.cache\."> 
    ExpiresDefault "now plus 1 year" 
</LocationMatch> 

您的lighthttpd配置應該是

server.modules = (
    "mod_expire", 
    "mod_setenv", 
) 
... 
$HTTP["url"] =~ "\.nocache\." { 
    setenv.add-response-header = ("Cache-Control" => "public, max-age=0, must-revalidate") 
    expire.url = ("" => "access plus 0 days") 
} 

$HTTP["url"] =~ "\.cache\." { 
    expire.url = ("" => "access plus 1 years") 
} 
+0

謝謝。我修復了lighttpd配置中的一些錯別字。感謝您將Apache配置轉換爲lighttpd。 – jfritz42

2
  • 的app.nocache.js在Web服務器上的瀏覽器WAS RELOADED(200 OK),因爲服務器上的文件比瀏覽器緩存更新。我確認了服務器返回的新文件的文件大小和時間戳是正確的。(這是關於服務器的HTTP響應的Chrome報告)

我不會依賴於此。我在Chrome的開發工具中看到了一些奇怪的行爲,使用網絡標籤和緩存(至少對我來說不是100%透明)。如有疑問,我通常還會諮詢Firebug。

所以可能Chrome仍然使用舊版本。它可能很久以前就已經決定,它不會再次重新加載資源。清除緩存應解決此問題。然後確保在重新加載頁面之前設置正確的緩存標題,請參閱Ideal HTTP cache control headers for different types of resources

3

有兩個簡單的解決方案(第一個第二個修改版本雖然)

1)將您的* .html文件重命名爲* .nocache.js,即將MyProject.html重命名爲MyProject.jsp 現在搜索你的位置在* MyProject.html

.nocache.js腳本
<script language="javascript" src="MyProject/MyProject.nocache.js"></script> 

添加一個動態變量作爲JS文件中的參數,這將確保實際內容被每次都從服務器返回。以下是例子

<script language="javascript" src="MyProject/MyProject.nocache.jsp?dummyParam=<%= "" + new java.util.Date().getTime() %>"></script> 

說明:dummyParam將是沒有用的,但將讓我們我們預期的結果,即會返回美國200代碼,而不是304

注意:如果你會使用這個技術,那麼你將需要以確保您指向正確的jsp文件來加載您的應用程序(在此更改之前,您正在使用HTML文件加載您的應用程序)。

2)如果您不想使用JSP解決方案,並且希望堅持使用您的html文件,那麼在加載nocache文件時,您將需要java腳本在客戶端動態添加唯一參數值。我假設現在給你的解決方案應該不是什麼大問題。

我已經成功地使用了第一種技術,希望這會有所幫助。

-1

在通過Apache未成功阻止緩存之後,我創建了一個bash腳本,該腳本在我的Linux Tomcat服務器上每分鐘運行一次cron作業。

#!/bin/bash 
# 
# Touches GWT nocache.js files in the Tomcat web app directory to prevent caching. 
# Execute this script every minute in a root cron job. 
# 
cd /var/lib/tomcat7/webapps 
find . -name '*nocache.js' | while read file; do 
    logger "Touching file '$file'" 
    touch "$file" 
done 
+0

使用根腳本來觸摸由您的網絡服務器提供的文件是一個壞主意 - 尤其是,因爲你應該做的是確保內容與正確的HTTP頭一起提供(如果瀏覽器或中間代理服務器真的緩存了內容,服務器甚至不會被問到)。 – R4zorax

5

我們有類似的問題。我們發現nocache.js的時間戳沒有使用gwt編譯進行更新,因此必須在構建時觸摸該文件。然後我們也應用了@Manolo CarrascoMoñino的修復。我寫了一篇關於這個問題的博客。 http://programtalk.com/java/gwt-nocachejs-cached-by-browser/

我們正在使用GWT的2.7版本,因爲評論也指出。

+1

時間戳不變是我們的問題。我相信這只是GWT 2.7中的一個bug。感謝您的博客文章! – Craigo

+0

很棒的回答。現在我學到了Shift + F5是第一次臨時解決方案。 – Tom

0

以認知模式打開頁面,以擺脫緩存問題並解除自己的阻止。

您需要配置其他註釋中提到的緩存時間。