【发布时间】:2016-04-08 02:38:18
【问题描述】:
我有一个 html 文件,可以通过浏览来访问
https://localhost:8080/contextRoot/home.html
此 html 使用 2 张图片:
<img src="https://localhost:8080/contextRoot/image1.jpg">
<img src="https://localhost:8080/static/images/image2.jpg">
第一个图像被打包在我的 war 文件中并且可以正常加载。当我重新加载页面时,它是从缓存中获取的,而不是重新下载它。我在浏览器的开发者工具中看到了这一点。
第二张图片也可以正常加载,但每次请求页面时都会下载。它永远不会被缓存。它使用一个特殊的 java servlet 来处理我们所说的静态内容:
<servlet>
<servlet-name>staticFileServlet</servlet-name>
<servlet-class>com.company.web.file.StaticFileServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>staticFileServlet</servlet-name>
<url-pattern>/static/*</url-pattern>
</servlet-mapping>
此 servlet 在计算机磁盘上搜索文件夹 C://images/ 以查找名为 image1 的文件,并通过将这些字节写入响应来提供它,同时还将内容类型标头指向响应(因此浏览器知道它正在接收的文件类型)。
我想我可能需要添加额外的标题来解释浏览器应该缓存这些内容。 Cache-control 标头可以在这里帮助我吗?但是,我认为浏览器足够聪明,可以缓存请求,无论我(不)使用什么标头。
这里是成功缓存的图像的响应标头(作为战争文件提供)
Accept-Ranges:bytes
Content-Length:354
Content-Type:image/gif
Date:Mon, 04 Jan 2016 09:43:42 GMT
ETag:W/"354-1449227028000"
Last-Modified:Fri, 04 Dec 2015 11:03:48 GMT
Server:Apache-Coyote/1.1
这是一个由 servlet 提供但未缓存的图像示例:
Cache-Control:max-age:864000
Content-Type:image/jpeg
Date:Mon, 04 Jan 2016 13:59:04 GMT
Server:Apache-Coyote/1.1
Transfer-Encoding:chunked
编辑:我的文件位于 SSL 连接后面,这可能导致缓存被拒绝。但是,我确定不是服务器拒绝此缓存,因为
- 它正在缓存一些图像。
- 响应中没有设置标头(pregma、etag、缓存控制...)。
谷歌浏览器会自动拒绝来自(某些)ssl 连接的缓存吗?
【问题讨论】:
-
打开您的开发者控制台,然后在清除缓存后重新加载页面,或者使用快捷方式刷新页面并忽略缓存(例如,Windows 上的 Chrome 是 CTRL+F5 或 SHIFT+CTRL+F5 )。对于这两个图像,请检查响应标头以查看是否有不同之处。
-
正在生成的图像具有标头 Last-Modified,而未缓存的图像则没有此标头。我在处理缓存控制、编译指示等的请求和响应中都没有看到任何标头。
-
我不知道正在使用哪个服务器(顺便提供的不是不重要的信息),但可能是它被配置为向 servlet 调用添加无缓存标头。
-
我正在使用 JBoss,它在后台使用 Apache-Coyote/1.1。当我使用 chrome 的开发人员工具时,我没有看到请求/响应中出现标题,如果 apache 自动添加它们,它们不应该在那里吗?