1

我正在做一些接近与 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“未修改”。

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

更新:

控制:必须重新验证

  • 铬合金

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

  • IE10

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

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

  • 铬合金

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

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

结论

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

4

1 回答 1

1

HTTP/1.1 规范(RFC2616,我的重点):

13.2.2 启发式过期

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

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

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

于 2013-11-04T11:09:26.827 回答