我正在接近与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修改的缓存的理解是它应该每次调用以检查内容是否已被修改?
更新
F5和ctrl + F5将调用服务器,在新选项卡中打开站点或重新启动浏览器将调用服务器,在同一选项卡中键入地址将不会调用服务器。 If-Modified-Since
仅在执行Ctrl + F5时清除,这意味着当内容未修改时,它可用于正确返回304
F5和ctrl + F5将调用服务器,在新选项卡中打开站点将不会调用服务器,在同一个选项卡中键入地址将不会调用服务器。在执行Ctrl + F5 或重新启动浏览器
时清除If-Modified-Since
只有在执行Ctrl + F5
时才会清除每个操作If-Modified-Since
的服务器
If-Modified-Since
调用服务器
结论
如果您想确保每次都要调用no-cache
,304
可能会更好
答案 0 :(得分:1)
来自HTTP/1.1 spec(RFC2616,我的重点):
13.2.2启发式过期
由于源服务器并不总是提供明确的到期时间, HTTP缓存通常分配启发式到期时间,使用 使用其他标头值的算法(例如Last-Modified 时间)估计合理的到期时间。 HTTP / 1.1 规范没有提供具体的算法,但确实强加了 对结果的最坏情况限制。自启发式到期 时间可能会损害语义透明度,他们应该使用它们 谨慎,并且我们鼓励原始服务器提供明确的 到期时间尽可能。
提供Last-Modified
标头并不等同于要求用户代理在每次需要服务器资源时检查更新。
理想情况下,您应尽可能添加Expires
标头。但是,添加标题Cache-Control: must-revalidate
应该会有所帮助。