我正在使用GWT开发一个Web应用程序,即使Web服务器发送了该文件的新副本,也看到浏览器中app.nocache.js
文件的疯狂问题!
我正在使用Eclipse来编译以DEV模式工作的应用程序。为了测试生产模式,我有一个虚拟机(Oracle VirtualBox),其中带有Ubuntu访客OS在我的主机计算机上运行(Windows 7)。我正在VM中运行LightTPD Web服务器。VM正在共享我的项目的战争目录,Web服务器正在为此DIR服务。
我将Chrome用作浏览器,但是在Firefox中也发生了同样的事情。
这是场景:
- 该应用程序的网页为空白。Accorind to Chrome的" Inspect Element"工具,这是因为它正在尝试获取
6E89D5C912DD8F3F806083C8AA626B83.cache.html
,但不存在(404 not found
)。 - 我检查了战争目录,果然,该文件不存在。
- 从Web服务器(200 OK)重新加载了浏览器上的
app.nocache.js
,因为服务器上的文件比浏览器缓存更新。我验证了服务器返回的新文件的文件大小和时间戳是正确的。(这是有关服务器的HTTP响应的信息Chrome报告) -
但是,如果我在浏览器上打开
app.nocache.js
,则JavaScript指的是6E89D5C912DD8F3F806083C8AA626B83.cache.html
!也就是说,即使Web服务器发送了新的app.nocache.js
,浏览器似乎也忽略了它,并一直使用其缓存副本! -
goge- google-> gwt compile in 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
避免浏览器缓存的最佳方法是将到期时间设置为现在,并添加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" )
}
我们也有类似的问题。我们发现nocache.js的时间戳没有使用GWT编译更新,因此必须触摸构建中的文件。然后,我们还应用了@Manolo CarrascoMoñino的修复程序。我写了一个有关此问题的博客。http://programTalk.com/java/gwt-nocachejs-cached-by-browser/
我们正在使用GWT的2.7版,因为该评论还指出了。
有两个直接解决方案(第二个是第一个修改版本,但)
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将无用
注意:如果您使用此技术,则需要确保您指向右JSP文件以加载应用程序(在此更改之前,您使用HTML文件加载了应用程序)。
2)如果您不想使用JSP解决方案并要坚持使用HTML文件,则在加载Nocache文件时,您将需要Java脚本在客户端端动态添加唯一的参数值。我假设现在对您的解决方案对您来说不应该很大。
我已经成功使用了第一技术,希望这会有所帮助。
- 浏览器上的app.nocache.js是从Web服务器重新加载的(200个OK),因为服务器上的文件比浏览器缓存更新。我验证了服务器返回的新文件的文件大小和时间戳是正确的。(这是有关服务器的HTTP响应的信息Chrome报告)
我不会依靠这个。我在Chrome的Dev工具中看到了一些奇怪的行为,其中包括网络选项卡与缓存结合使用(至少对我而言,这不是100%透明的)。如有疑问,我通常仍然会咨询Firebug。
因此,也许Chrome仍然使用旧版本。它可能很久以前就决定了,它将不必再重新加载资源了。清除缓存应解决此问题。然后确保在重新加载页面之前设置正确的缓存标头,例如理想的HTTP缓存控制标头,用于不同类型的资源。
以Cognito模式打开页面,以获取缓存问题并解除自己的限制。p>您需要如其他注释中提到的配置缓存时间。
在未能通过Apache阻止缓存后,我创建了一个root root每分钟运行的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