关于使用脚本请求服务器端资源无法缓存的问题
在使用脚本请求服务器端资源时(如图片),会出现重复下载资源的问题,这个问题只在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 filterprivate static final boolean SIMULATE_SLOWNESS = false;// date format for headerprivate static final SimpleDateFormat DATEFORMAT = new SimpleDateFormat("EEE, d MMM yyyy 00:00:00 z", Locale.US);;// regexp Pattern objects precompiledprivate List patterns = new ArrayList();/** * {@inheritDoc} */public void init(FilterConfig config) throws ServletException {String patternParam = config.getInitParameter("patterns");// parse patternsif (patternParam != null) {String[] patternArr = patternParam.split(",");for (int i = 0; i < patternArr.length; i++) {String pattern = patternArr;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 patternsif (isMatch(path)) {if (LOG.isDebugEnabled()) {LOG.debug(getHeaderInfo(httpRequest));}// check if the browser asks if-modifiedif (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 responseif (SIMULATE_SLOWNESS) {delay(path);}// turn on caching for everything served:addCacheHeader(httpResponse, path);}}// forward in chainchain.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 neededhttpResponse.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>
页:
[1]