C# 上次修改缓存的问题

C# 上次修改缓存的问题,c#,caching,http-headers,owin,C#,Caching,Http Headers,Owin,我正在和奥温做一些接近金属的事情。 我有一个输出Java脚本的owin中间件。看起来像这样(相关部分) 公共覆盖任务调用(IOwinContext上下文) { var-response=context.response; response.ContentType=“应用程序/javascript”; response.StatusCode=200; if(ClientCached(context.Request,scriptBuildDate)) { response.StatusCode=30

我正在和奥温做一些接近金属的事情。 我有一个输出Java脚本的owin中间件。看起来像这样(相关部分)

公共覆盖任务调用(IOwinContext上下文)
{
var-response=context.response;
response.ContentType=“应用程序/javascript”;
response.StatusCode=200;
if(ClientCached(context.Request,scriptBuildDate))
{
response.StatusCode=304;
响应。标题[“内容长度”]=“0”;
response.Body.Close();
response.Body=Stream.Null;
返回Task.FromResult(空);
}
response.Headers[“Last Modified”]=scriptBuildDate.ToUniversalTime().ToString(“r”);
返回response.WriteAsync(js);
}
private bool ClientCached(IOwinRequest请求,DateTime contentModified)
{
string header=request.Headers[“如果修改自”];
if(标题!=null)
{
日期时间是修改后的;
if(DateTime.TryParse(标题,out isModifiedSince))
{
返回isModifiedSince>=contentModified;
}
}
返回false;
}
如果客户端未缓存,它将输出200,并将上次修改的日期添加到标头,如果客户端缓存,它将输出304“未修改”

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

更新:

控件:必须重新验证
F5和ctrl+F5将调用服务器,在新选项卡中打开站点或重新启动浏览器将调用服务器,在同一选项卡中键入地址将不会调用服务器<代码>如果修改,因为仅在执行Ctrl+F5时清除,这意味着当内容未修改时,可以使用它正确返回304

  • IE10
F5和ctrl+F5将调用服务器,在新选项卡中打开站点将不会调用服务器,在同一选项卡中键入地址将不会调用服务器<代码>如果在执行Ctrl+F5或重新启动浏览器时被清除

缓存控制:无缓存和杂注:无缓存
如果修改,将为每个操作调用服务器,因为只有在执行Ctrl+F5时才清除

  • 如果在重新启动浏览器和Ctrl+F5时都清除了,则将为每个操作调用服务器
结论

如果您想确保它每次都从(RFC2616,我的重点)调用检查
304
,则
no cache
可能更好:

13.2.2启发式失效 由于源服务器并不总是提供明确的过期时间, HTTP缓存通常分配启发式过期时间,采用 使用其他标头值(例如上次修改的 时间)以估计合理的到期时间。HTTP/1.1 规范并没有提供具体的算法,但会强制执行 对其结果的最坏情况限制。自启发式过期 时间可能会影响语义透明度,它们应该被使用 谨慎地,我们鼓励源服务器提供明确的 尽可能延长过期时间

提供上次修改的
标题并不等同于要求用户代理在每次需要来自服务器的资源时检查更新

理想情况下,您应该尽可能添加
Expires
标题。但是,添加标头
缓存控制:必须重新验证
应该会有所帮助。

来自(RFC2616,我的重点):

13.2.2启发式失效 由于源服务器并不总是提供明确的过期时间, HTTP缓存通常分配启发式过期时间,采用 使用其他标头值(例如上次修改的 时间)以估计合理的到期时间。HTTP/1.1 规范并没有提供具体的算法,但会强制执行 对其结果的最坏情况限制。自启发式过期 时间可能会影响语义透明度,它们应该被使用 谨慎地,我们鼓励源服务器提供明确的 尽可能延长过期时间

提供上次修改的
标题并不等同于要求用户代理在每次需要来自服务器的资源时检查更新


理想情况下,您应该尽可能添加
Expires
标题。但是,添加标头
缓存控制:必须重新验证
应该会有所帮助。

是否还有“最长期限”或“过期”发送到客户端?这些可能会导致您看到的“不调用服务器,使用客户端缓存”行为。是否也会向客户端发送“最长使用期限”或“过期”?这些可能会导致您看到的“不要调用服务器,使用客户端缓存”行为嗯,必须重新验证似乎无法达到目的,如果usedAha,它将忽略上次修改的头,它的IE 10以这种方式运行,在Chrome中它将不会删除上次修改的头请参见-
必须重新验证
才能工作,客户机需要知道资源何时过时。因此,也许
缓存控制:max age=0,must revalidate
会更好。嗯,must revalidate似乎无法达到目的,如果usedAha,它将忽略最后修改的头,它的IE 10以这种方式运行,在Chrome中它不会删除最后修改的头请参见-
必须重新验证
才能工作,客户机需要知道资源何时过时。所以也许
缓存控制:max age=0,必须重新验证
会更好。
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;
}