在使用脚本请求服务器端资源时(如图片),会出现重复下载资源的问题,这个问题只在IE中出现过,经查找,发现一个解决方式:加一个过滤器,代码如下:、
import java.io.IOException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Enumeration; import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * Filter fixes the IE image cache bug described at folowing locations. * http://mir.aculo.us/articles/2005/08/28/internet-explorer-and-ajax-image-caching-woes * http://www.netmechanic.com/news/vol6/javascript_no1.htm * http://www.bazon.net/mishoo/articles.epl?art_id=958 * http://ahinea.com/en/tech/ie-dhtml-image-caching.html * * @author zluspai */ public class IEImageCacheBugFixFilter implements Filter { private static final Log LOG = LogFactory.getLog(IEImageCacheBugFixFilter.class); // if the slowness is simulated by this filter private static final boolean SIMULATE_SLOWNESS = false; // date format for header private static final SimpleDateFormat DATEFORMAT = new SimpleDateFormat("EEE, d MMM yyyy 00:00:00 z", Locale.US);; // regexp Pattern objects precompiled private List patterns = new ArrayList(); /** * {@inheritDoc} */ public void init(FilterConfig config) throws ServletException { String patternParam = config.getInitParameter("patterns"); // parse patterns if (patternParam != null) { String[] patternArr = patternParam.split(","); for (int i = 0; i < patternArr.length; i++) { String pattern = patternArr[i]; try { Pattern p = Pattern.compile(pattern); this.patterns.add(p); } catch (PatternSyntaxException syntaxex) { LOG.warn("Exception when parsing pattern:" + pattern, syntaxex); } } } } /** * Check if the path matches with the regexp patterns. * * @param path The path string * @return If matched */ private boolean isMatch(String path) { for (Iterator iPatterns = patterns.iterator(); iPatterns.hasNext();) { Pattern pattern = (Pattern) iPatterns.next(); if (pattern.matcher(path).matches()) { if (LOG.isDebugEnabled()) { LOG.debug("matched: " + pattern.pattern() + " ,path:" + path); } return true; } } return false; } /** * {@inheritDoc} */ public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { if (request instanceof HttpServletRequest) { HttpServletRequest httpRequest = (HttpServletRequest) request; HttpServletResponse httpResponse = (HttpServletResponse) response; String path = httpRequest.getRequestURI(); // check patterns if (isMatch(path)) { if (LOG.isDebugEnabled()) { LOG.debug(getHeaderInfo(httpRequest)); } // check if the browser asks if-modified if (httpRequest.getHeader("if-modified-since") != null) { // tell the browser that resource not changed, so it can use // the cached version! httpResponse.setStatus(304); LOG.debug("returning 304 for path:" + path); return; } // uncomment this to simulate slow response if (SIMULATE_SLOWNESS) { delay(path); } // turn on caching for everything served: addCacheHeader(httpResponse, path); } } // forward in chain chain.doFilter(request, response); } /** * Add cache header to the response. * * @param httpResponse The response * @param path The current path */ private void addCacheHeader(HttpServletResponse httpResponse, String path) { httpResponse.setHeader("Cache-control", "max-age=10000000"); Calendar c = Calendar.getInstance(); String date = DATEFORMAT.format(c.getTime()); httpResponse.setHeader("Last-Modified", date); // expires is one more year: c.add(Calendar.YEAR, 1); date = DATEFORMAT.format(c.getTime()); httpResponse.setHeader("Expires", date); // unique tag needed httpResponse.setHeader("ETag", path); } /** * Log header info arrived in request. * * @param httpRequest The HttpRequest object. * @return String containig all header info. */ private String getHeaderInfo(HttpServletRequest httpRequest) { StringBuffer info = new StringBuffer(); Enumeration headernames = httpRequest.getHeaderNames(); while (headernames.hasMoreElements()) { String name = (String) headernames.nextElement(); info.append(name + "=" + httpRequest.getHeader(name)).append("\n"); } return info.toString(); } /** * Implemented Filter method. */ public void destroy() { } /** * Delay a bit before serving the response. * * @param path The current request url path */ private void delay(String path) { // long delay: try { LOG.info("Waiting before serving of:" + path); Thread.sleep(2000); } catch (InterruptedException e) { LOG.debug("ignored exception", e); } } }
To use this filter you will need to map it in the web.xml, for example:
<!-- fixes IE caching problem for Ajax requests --> <!-- several directories can be cached: dojo, customdoj, images, scripts --> <filter> <filter-name>IEImageCacheBugFixFilter</filter-name> <filter-class>IEImageCacheBugFixFilter</filter-class> <init-param> <param-name>patterns</param-name> <param-value>.*\.(g|G)(i|I)(f|F),.*\.(j|J)(p|P)(g|G),.*/dojo/.*,.*/images/.*,.*/scripts/.*,</param-value> </init-param> </filter> <filter-mapping> <filter-name>IEImageCacheBugFixFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>