3

我正在使用 .aspx 页面根据给定的参数从文件系统中提供图像文件。

Server.Transfer(imageFilePath);

当此代码运行时,会提供图像,但不会创建Last-Modified HTTP 标头。与同一个文件相反,直接从同一服务器上的 URL 调用。

因此浏览器不会发出If-Modified-Since并且不会缓存响应。

有没有办法让服务器像通常直接请求文件(在这种情况下为图像)一样创建 HTTP 标头,还是我必须手动创建标头?

4

2 回答 2

1

当您对文件进行传输时,服务器将返回与文件相同的标头.aspx,因为它基本上是由 .NET 引擎执行的。

你基本上有两个选择:

  • 改为重定向到文件,以便浏览器发出请求。

  • 设置您想要的标题,并使用Request.BinaryWrite(或类似)在响应中将文件数据发送回。

于 2012-10-25T13:33:38.393 回答
1

我将扩展@Guffa 的答案并分享我选择的解决方案。

调用该Server.Transfer方法时,.NET 引擎将其视为一个.aspx页面,因此在提供静态文件时它不会添加所需的适当 HTTP 标头(例如用于缓存)。

有三个选项

  • 使用Response.Redirect,因此浏览器发出适当的请求
  • 设置所需的标题并Request.BinaryWrite用于提供内容
  • 设置所需的标题并调用Server.Transfer

我选择第三个选项,这是我的代码:

        try
        {
            DateTime fileLastModified = File.GetLastWriteTimeUtc(MapPath(fileVirtualPath));
            fileLastModified = new DateTime(fileLastModified.Year, fileLastModified.Month, fileLastModified.Day, fileLastModified.Hour, fileLastModified.Minute, fileLastModified.Second);
            if (Request.Headers["If-Modified-Since"] != null)
            {
                DateTime modifiedSince = DateTime.Parse(Request.Headers["If-Modified-Since"]);

                if (modifiedSince.ToUniversalTime() >= fileLastModified)
                {
                    Response.StatusCode = 304;
                    Response.StatusDescription = "Not Modified";
                    return;
                }
            }
            Response.AddHeader("Last-Modified", fileLastModified.ToString("R"));
        }
        catch
        {
            Response.StatusCode = 404;
            Response.StatusDescription = "Not found";
            return;
        }
        Server.Transfer(fileVirtualPath);
于 2012-10-25T15:24:05.150 回答