1、
开发环境
客户端:安卓+webview(vuejs)
服务器端:tomcat 8.0
2、问题
使用安卓原生+web(基于webpack+vuejs)的方式开发了一个安卓应用,因为web的js文件较大,大概有400k左右,每次从app中打开该页面都要从新从服务器端下载页面的html、js和图片等静态资源,反应速度比较慢了,大概须要三四秒(若是用户网速慢的话,则须要更久),体验效果就很很差。
因此就考虑是否是能够只在第一次打开的时候下载,而后就缓存在客户端,之后只有有更新的时候才下载,可是开发人员在将安卓的webview的缓存选项设置为
LOAD_DEFAULT以后,而且在html的head加上以下meta标签,可是彷佛没有效果,有时候会缓存,有时候有从新下载,和预期的行为不一致。
<meta http-equiv="Cache-Control" content="max-age=
604800
"/>
3、分析
首先
安卓的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协议缓存
不过咱们通常都不会单独使用某一项。css
因此我估计这个meta tag在android的webview中 是没有做用的。
4、解决方案
在后端代码中添加了过滤器,而后回复的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>
附录、参考资料