标签:
一、开发环境
客户端:安卓+webview(vuejs)
服务器端:tomcat 8.0
二、问题
使用安卓原生+web(基于webpack+vuejs)的方式开发了一个安卓应用,由于web的js文件较大,大概有400k左右,每次从app中打开该页面都要重新从服务器端下载页面的html、js和图片等静态资源,反应速度比较慢了,大概需要三四秒(如果用户网速慢的话,则需要更久),体验效果就很不好。
所以就考虑是不是可以只在第一次打开的时候下载,然后就缓存在客户端,以后只有有更新的时候才下载,但是开发人员在将安卓的webview的缓存选项设置为LOAD_DEFAULT之后,并且在html的head加上如下meta标签,但是似乎没有效果,有时候会缓存,有时候有重新下载,和预期的行为不一致。
<meta http-equiv="Cache-Control" content="max-age=604800"/>
三、分析
首先安卓的webview的缓存选项设置为LOAD_DEFAULT应该没错,这点没有太大疑问,我们就是想要 根据cache-control决定是否从网络上取数据。
然后重点就是在html中的这个Cache-Control设置,分析之后发现这其实是一个http协议范畴的内容,下图是《http 权威指南》中的描述。
所以现在要验证这个在html的cache-control meta标签是否起作用,可以从两个方面来找原因:
(1) 首先可以看看tomcat是否支持,比如他在遇到html的时候,是否会解析其中的cache-control meta设置,然后在回复的http报文头上加上Cache-Control,使用wireshark抓取的html页面响应的报文头如下,这说明tomcat默认是不支持解析html页面头上的cache-control meta标签的。
(2) 然后就是看安卓的webview是否支持解析该meta标签了,这点在android官方的webview说明中没有招到,可能要去webkit的官方去找。
但是一篇博文上招到如下说明:
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" /><meta http-equiv="Pragma" content="no-cache" /><meta http-equiv="Expires" content="0" />
但,实际情况是,这些meta只能在file:// 本地文件中使用,如果是服务器则默认被覆盖。现在目前主流的就是使用HTTP1.1协议缓存
不过我们一般都不会单独使用某一项。
所以我估计这个meta tag在android的webview中 是没有作用的。
四、解决方案
在后端代码中添加了过滤器,然后回复的http报文头上就有cache-control,就可以按照设置的max-age正确缓存了。
Filter的代码: - public class ResponseHeaderFilter implements Filter {
- FilterConfig fc;
-
- public void doFilter(ServletRequest req, ServletResponse res,
- FilterChain chain) throws IOException, ServletException {
- HttpServletResponse response = (HttpServletResponse) res;
-
- for (Enumeration e = fc.getInitParameterNames(); e.hasMoreElements();) {
- String headerName = (String) e.nextElement();
- response.addHeader(headerName, fc.getInitParameter(headerName));
- }
-
- chain.doFilter(req, response);
- }
-
- public void init(FilterConfig filterConfig) {
- this.fc = filterConfig;
- }
-
- public void destroy() {
- this.fc = null;
- }
-
- }
web.xml里的巧妙配置: - <filter>
- <filter-name>NoCache</filter-name>
- <filter-class>apis.server.common.util.ResponseHeaderFilter</filter-class>
- <init-param>
- <param-name>Cache-Control</param-name>
- <param-value>no-cache, must-revalidate</param-value>
- </init-param>
- </filter>
- <filter>
- <filter-name>CacheForWeek</filter-name>
- <filter-class>apis.server.common.util.ResponseHeaderFilter</filter-class>
- <init-param>
- <param-name>Cache-Control</param-name>
- <param-value>max-age=604800, public</param-value>
- </init-param>
- </filter>
-
- <filter-mapping>
- <filter-name>NoCache</filter-name>
- <url-pattern>*.do</url-pattern>
- </filter-mapping>
- <filter-mapping>
- <filter-name>CacheForWeek</filter-name>
- <url-pattern>/images/*</url-pattern>
- </filter-mapping>
- <filter-mapping>
- <filter-name>CacheForWeek</filter-name>
- <url-pattern>/img/*</url-pattern>
- </filter-mapping>
- <filter-mapping>
- <filter-name>CacheForWeek</filter-name>
- <url-pattern>/icons/*</url-pattern>
- </filter-mapping>
- <filter-mapping>
- <filter-name>CacheForWeek</filter-name>
- <url-pattern>/ext/*</url-pattern>
- </filter-mapping>
- <filter-mapping>
- <filter-name>CacheForWeek</filter-name>
- <url-pattern>*.js</url-pattern>
- </filter-mapping>
- <filter-mapping>
- <filter-name>CacheForWeek</filter-name>
- <url-pattern>*.css</url-pattern>
- </filter-mapping>
附录、参考资料
WebApp:如何让安卓的webview缓存webapp的html、js和图片等资源
标签:
原文地址:http://www.cnblogs.com/strinkbug/p/5836534.html