【问题标题】:Problems with Last-Modified cachingLast-Modified 缓存的问题
【发布时间】:2013-11-04 10:57:41
【问题描述】:

我正在与 Owin 进行一些接近金属 HTTP 的纠缠。 我有一个输出 javascripts 的 owin 中间件。看起来是这样的(相关部分)

public override Task Invoke(IOwinContext context)
{
    var response = context.Response;
    response.ContentType = "application/javascript";
    response.StatusCode = 200;

    if (ClientCached(context.Request, scriptBuildDate))
    {
        response.StatusCode = 304;
        response.Headers["Content-Length"] = "0";
        response.Body.Close();
        response.Body = Stream.Null;

        return Task.FromResult<Object>(null);
    }

    response.Headers["Last-Modified"] = scriptBuildDate.ToUniversalTime().ToString("r");
    return response.WriteAsync(js);
}

private bool ClientCached(IOwinRequest request, DateTime contentModified)
{
    string header = request.Headers["If-Modified-Since"];

    if (header != null)
    {
        DateTime isModifiedSince;
        if (DateTime.TryParse(header, out isModifiedSince))
        {
            return isModifiedSince >= contentModified;
        }
    }

    return false;
}

如果它没有被客户端缓存,它会输出 200,并在头部添加一个 Last-Modified 日期,如果它的客户端被缓存,它会输出 304“Not modified”。

问题是客户端不会再次调用 url,除非他们在浏览器中执行硬 F5。我对 Last modified 缓存的理解是每次都应该调用来检查内容是否被修改过?

更新:

控制:必须重新验证

F5 和 ctrl+F5 将调用服务器,在新选项卡中打开站点或重新启动浏览器将调用服务器,在同一选项卡中键入地址将不会调用服务器。 If-Modified-Since 只在 Ctrl+F5 时清除,表示在内容未修改时可以正确返回 304

  • IE10

F5 和 ctrl+F5 将调用服务器,在新选项卡中打开站点不会调用服务器,在同一选项卡中键入地址不会调用服务器。 If-Modified-Since 在执行 Ctrl+F5 或重新启动浏览器时清除

Cache-Control: no-cache 和 Pragma: no-cach

会为每个操作调用服务器If-Modified-Since 仅在执行 Ctrl+F5 时清除

  • 将为每个操作调用服务器 If-Modified-Since 为重新启动浏览器和 Ctrl+F5 清除

结论

看起来no-cache 可能会更好,如果你想确保它每次都调用来检查304

【问题讨论】:

  • 是否还会向客户端发送“max-age”或“expires”?这些可能会导致您看到的“不调用服务器,使用客户端缓存”行为

标签: c# caching http-headers owin


【解决方案1】:

来自HTTP/1.1 spec(RFC2616,我的重点):

13.2.2 启发式过期

由于源服务器并不总是提供明确的过期时间, HTTP 缓存通常分配启发式过期时间,采用 使用其他标头值的算法(例如 Last-Modified 时间)来估计一个合理的到期时间。 HTTP/1.1 规范没有提供具体的算法,但确实强加了 对他们的结果的最坏情况限制。由于启发式过期 时间可能会损害语义透明度,他们应该使用 谨慎,我们鼓励源服务器提供明确的 尽可能多的过期时间

提供Last-Modified 标头并不等同于要求用户代理在每次需要服务器资源时检查更新。

理想情况下,您应该尽可能添加Expires 标头。但是,添加标题 Cache-Control: must-revalidate 应该会有所帮助。

【讨论】:

  • 嗯,must-revalidate 似乎违背了目的,如果使用它会忽略最后修改的标题
  • 啊哈,它的 IE 10 以这种方式运行,在 Chrome 中它不会删除最后修改的标头
  • stackoverflow.com/questions/7573466/… -- 似乎must-revalidate 工作,客户端需要知道资源何时变得陈旧。所以也许Cache-Control: max-age=0, must-revalidate 会更好。
猜你喜欢
  • 2011-02-02
  • 1970-01-01
  • 2014-03-31
  • 2011-08-16
  • 2011-07-13
  • 2011-03-03
  • 1970-01-01
  • 1970-01-01
  • 2016-06-24
相关资源
最近更新 更多