缓存问题w。自定义Web服务器。 Chrome不会发送If-Modified-Since标头,但仍然会不时地获取304

时间:2014-03-31 11:10:23

标签: google-chrome caching http-headers http-status-code-304 nanohttpd

我正在使用基于NanoHTTPD构建的自定义Web服务器,我已经添加了缓存功能。代码中只有一部分可以抛出304 Not Modified响应:

           if(isNotModified(f,header,parms)){// if requested file has not been modified, let's make the browser use it's cache
                Response r= new Response( Response.Status.NOT_MODIFIED, MIME_PLAINTEXT,(String)null,null);
                //r.addHeader(key,val);
                r.addHeader("Last-Modified",""+f.lastModified());//FIXME: doesnt work with wget + prob others as well
                r.addHeader("ETag",f.getPath()+f.lastModified());

                return r;
            }

isNotModified方法:

/**
 * check if the file has been modified since the last time client requested it
 * */
public boolean isNotModified(File ff,Properties header, Properties params){
    if(params.getProperty("bust")!= null ||params.getProperty("cachebust")!=null)
        return false; 
    if(ff.getName().endsWith(".pg"))
        return false;
    if(ff.getPath().indexOf("/api/")>=0)
        return false;
    if("no-cache".equalsIgnoreCase(header.getProperty("cache-control")))
        return false;

    String mod = header.getProperty("if-modified-since");//names are converted to lowercase fwiw

    if(mod==null)//this should happen whenever browser sends no if-modified-since
        return false;

    try{
        long l = Long.parseLong(mod);
        if(ff.lastModified()<=l)
            return true;
    }catch(Exception ex){
        ex.printStackTrace();
    }

    return false;
}

出于某种原因,即使在标题中没有指定If-Modified-Since(或与缓存相关的任何内容),我仍然会获得304(至少)Chrome。这导致浏览器将资源解释为空字符串并破坏事物。

2 个答案:

答案 0 :(得分:2)

Chrome使用响应代码304来指示响应是从本地缓存提供的,而不是从服务器提取的。由于这不是真正的HTTP响应,而是一个虚假的对象,它可能会让很多开发人员感到困惑。它的属性与真正的响应对象不同。对于AJAX请求尤其如此。

建议的解决方法是发送Expires标头而不是Last-modified,以便在浏览器使用本地缓存时以及浏览器向服务器发出请求时具有准确的控制权。

Expires标题

为例
  • 在达到Expires标题的时间之前,您将获得虚假的HTTP 304响应

  • 此后,浏览器向服务器发出实际请求

答案 1 :(得分:0)

我修复了所有标题并添加了一个没有任何帮助的Expires标题,但是添加它可以解决问题:

if("no-cache".equalsIgnoreCase(header.getProperty("pragma")))
        return false;