gpt4 book ai didi

c# - 来自 HttpHandler 的图像不会在浏览器中缓存

转载 作者:IT王子 更新时间:2023-10-29 04:33:56 25 4
gpt4 key购买 nike

我正在使用 IHttpHandler 提供来自数据库的图像。相关代码在这里:

public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "image/jpeg";
int imageID;
if (int.TryParse(context.Request.QueryString["id"], out imageID))
{
var photo = new CoasterPhoto(imageID);
if (photo.CoasterPhotoID == 0)
context.Response.StatusCode = 404;
else
{
byte[] imageData = GetImageData(photo);
context.Response.OutputStream.Write(imageData, 0, imageData.Length);
context.Response.Cache.SetCacheability(HttpCacheability.Public);
context.Response.Cache.SetExpires(DateTime.Now.AddMinutes(5));
context.Response.Cache.SetLastModified(photo.SubmitDate);
}
}
else
context.Response.StatusCode = 404;
}

问题是浏览器不会缓存图像,大概是因为我没有在响应 header 中指明正确的内容。在 HttpCachePolicy 属性上调用方法的部分是我认为会强制浏览器保留图像的部分,但事实并非如此。我认为处理程序返回没有图像的 304 状态代码是“正确的”,对吧?我如何使用 IHttpHandler 实现这一目标?

编辑:

根据最佳答案,我运行了这段代码,它完全解决了问题。是的,它需要一些重构,但它通常展示了我所追求的。相关部分:

if (!String.IsNullOrEmpty(context.Request.Headers["If-Modified-Since"]))
{
CultureInfo provider = CultureInfo.InvariantCulture;
var lastMod = DateTime.ParseExact(context.Request.Headers["If-Modified-Since"], "r", provider).ToLocalTime();
if (lastMod == photo.SubmitDate)
{
context.Response.StatusCode = 304;
context.Response.StatusDescription = "Not Modified";
return;
}
}
byte[] imageData = GetImageData(photo);
context.Response.OutputStream.Write(imageData, 0, imageData.Length);
context.Response.Cache.SetCacheability(HttpCacheability.Public);
context.Response.Cache.SetLastModified(photo.SubmitDate);

最佳答案

AFAIK,负责发送 304 Not Modified,这意味着我不知道 .Net 框架中有任何东西在你发送“动态”图像数据的这个用例中为你做这件事.您将要做的(伪代码):

  • 检查请求中的 If-Modified-Since header 并解析日期(如果存在)。
  • 将其与原始图像(动态生成的)图像的最后修改日期进行比较。跟踪这可能是该问题解决方案中最复杂的部分。在您目前的情况下,您正在根据每个请求重新创建图像;除非万不得已,否则您不想这样做。
  • 如果浏览器拥有的文件日期比您拥有的图像日期更新或相同,请发送 304 Not Modified。
  • 否则,继续您当前的实现

跟踪最后修改时间的一种简单方法是在文件系统上缓存新生成的图像,并保留一个内存字典,将图像 ID 映射到包含磁盘上的文件名和最后修改的结构日期。使用 Response.WriteFile 从磁盘发送数据。当然,每次重新启动工作进程时,字典都会为空,但您至少可以获得一些缓存优势,而不必在某处处理持久缓存信息。

您可以通过将“图像生成”和“通过 HTTP 发送图像”的关注点分离到不同的类中来支持这种方法。现在,您正在同一个地方做两件截然不同的事情。

我知道这听起来有点复杂,但这是值得的。我最近刚刚实现了这种方法,在处理时间和带宽使用方面的节省令人难以置信。

关于c# - 来自 HttpHandler 的图像不会在浏览器中缓存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/994135/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com