5

在我们的 Asp.Net 应用程序中,我们有一个 IHttpHandler 处理图像请求。Handler 使用一个特殊的 id 来调用,该 id 标识了我们的图像缓存中的图像。一旦图像投入现金,它就永远不会改变。我的问题是:

是否可以始终为带有“If-Modified-Since”标头的请求返回 http 状态代码 304,而无需实际检查给定日期?原因是浏览器必须已经拥有图像的副本(因为它提供了 modified-since 标头)。

这将使生活更轻松,因为我们(还)不跟踪图像创建日期。

这是实际代码(更新:我现在按照 Aristos 的建议在服务器响应中包含了 if-modified 标头):

public void ProcessRequest(HttpContext context)
{
    if (!String.IsNullOrEmpty(context.Request.Headers["If-Modified-Since"])) {
        //Is this okay?
        context.Response.StatusCode = 304;
        context.Response.StatusDescription = "Not Modified";
        return;
    }
    var thumbnailId = context.Request.QueryString["thumbnail"];
    using (var thumbnailCache = new CThumbnailCache()) {
        var imageBytes = thumbnailCache.GetImageById(thumbnailId);

        context.Response.ContentType = "image/png";
        var outputStream = context.Response.OutputStream;
        outputStream.Write(imageBytes, 0, imageBytes.Count());
        context.Response.Cache.SetCacheability(HttpCacheability.Public);
        context.Response.Cache.SetLastModified(DateTime.UtcNow);
        // added after Aristos post
        context.Response.AddHeader("If-Modified-Since", DateTime.UtcNow.ToString("r"));

        const int maxAge = 86400 * 14; // 14 Tage
        context.Response.Cache.SetExpires(DateTime.Now.AddSeconds(maxAge));
        context.Response.Cache.SetMaxAge(new TimeSpan(0, 0, maxAge));
        context.Response.CacheControl = "private";
        context.Response.Cache.SetValidUntilExpires(true);

    }
}
4

2 回答 2

3

没关系,从您获得If-Modified-Since资源在浏览器上的那一刻起,您就可以决定是否让它保持原样。

我喜欢在这里说你们两个的想法。您似乎没有设置此标头,因此您可能无法通过浏览器获取它。

要使此实际工作,您需要添加此行

context.Response.AddHeader("If-Modified-Since", LastModifledOfImage.ToString()); 

或者像您发送当前日期时间一样:

context.Response.AddHeader("If-Modified-Since", DateTime.UtcNow.ToString());

当你发送图像。我看到您使用的是,SetLastModified但这是设置Last-Modified标题而不是您检查的标题。

如果可能,请考虑将这些图像设为实际静态,因为即使这样也会If-Modified-Since调用服务器,但实际静态资源会直接从浏览器缓存中获取图像,而无需询问服务器。

于 2012-07-02T11:42:07.857 回答
2

按规范:

如果客户端已经执行了一个条件 GET 请求并且允许访问,但是文档没有被修改,服务器应该用这个状态码来响应。

所以,是的,看起来这些条件都满足了。请务必在您的回复中再次包含 Date 标头。

于 2012-07-02T11:43:09.240 回答