【问题标题】:Cache-Control headers not sent in response despite being configured on response object尽管在响应对象上进行了配置,但未在响应中发送 Cache-Control 标头
【发布时间】:2015-07-23 10:58:15
【问题描述】:

我正在尝试在 ASP.NET MVC Web API 中设置缓存标头,但来自 IIS 的响应表明设置的 CacheControl 值被忽略。

我最初的假设是我在 System.Web.Http.Cors 中使用了 EnableCorsAttribute,这在这个用例中是必需的。但是,即使没有该属性,响应 Cache-Control 标头仍然是“私有的”。

我在这里做错了吗?

    // GET api/<version>/content
    // [EnableCors(origins: "*", headers: "*", methods: "*")]
    public HttpResponseMessage Get(HttpRequestMessage request)
    {
        int cacheMaxAgeSeconds;

        string cacheMaxAgeString = request.GetQueryString("cache-max-age") ?? request.GetQueryString("cache-max-age-seconds");

        string rawUri = request.RequestUri.ToString();

        try
        {
            cacheMaxAgeSeconds = cacheMaxAgeString == null ? Config.ApiCacheControlMaxSeconds : int.Parse(cacheMaxAgeString);
        }
        catch (Exception ex)
        {
            cacheMaxAgeSeconds = Config.ApiCacheControlMaxSeconds;

            //... 
        }

        try
        {
            //...

            var response = new HttpResponseMessage(HttpStatusCode.OK)
            {
                Content = new StringContent("...", Encoding.UTF8, "application/json")
            };

            response.Headers.CacheControl = new CacheControlHeaderValue
            {
                Public = true,
                MaxAge = TimeSpan.FromSeconds(cacheMaxAgeSeconds)
            };

            return response;
        }
        catch (Exception apiEx)
        {
            //...
        }
    }

回应

HTTP/1.1 200 OK
Cache-Control: private
Content-Type: application/json; charset=utf-8
Date: Thu, 23 Jul 2015 10:53:17 GMT
Server: Microsoft-IIS/7.5
Set-Cookie: ASP.NET_SessionId=knjh4pncbrhad30kjykvwxyz; path=/; HttpOnly
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Content-Length: 2367
Connection: keep-alive

【问题讨论】:

  • 您是否有理由尝试在github.com/filipw/AspNetWebApi-OutputCache 之类的东西上推出自己的产品?
  • 是的,我实际上希望调用者能够指定缓存周期。该值从查询字符串中读取并馈送到缓存控制标头值中。
  • 嗯,如果有人知道这个问题的答案,那将是 twitter.com/filip_woj(上述 nuget 包的创建者)可能值得在 Twitter 上与他联系。
  • 好电话。在我这样做之前,我将浏览该项目,看看是否有任何不同的做法。当我有机会检查时会更新。

标签: c# asp.net-web-api http-caching


【解决方案1】:

下面的代码在 vanilla WebApi 应用程序(System.Web.Http 4.0.0.0)中正确设置了“cache-control: public, max-age=15”。所以...可能不是 WebApi 本身导致了问题。

您的项目中可能有一些改变缓存设置的魔法(想想全局操作过滤器或类似的东西)。或者,也许您正在通过重写 HTTP 标头的代理。

    public HttpResponseMessage Get()
    {
        var content = new JavaScriptSerializer().Serialize(new { foo = "bar" });

        var response = new HttpResponseMessage(HttpStatusCode.OK)
        {
            Content = new StringContent(content, Encoding.UTF8, "application/json")
        };

        response.Headers.CacheControl = new CacheControlHeaderValue
        {
            Public = true,
            MaxAge = TimeSpan.FromSeconds(15)
        };

        return response;
    }

// returns in the response: "Cache-Control: public, max-age=15"

【讨论】:

    【解决方案2】:

    几周后才知道答案:

    在运行 debug 构建时,Cache-Control 标头似乎设置为“私有”。当我使用发布版本运行时,问题就消失了。

    【讨论】:

      【解决方案3】:

      添加其他可能导致此问题的内容:

      您通过 Owin 管道运行。

      在这种情况下,您需要在定义如下的 Owin 中间件中设置标头:

      class MiddleWare : OwinMiddleware
      {
          public MiddleWare(OwinMiddleware next)
          : base(next)
          {
          }
          public override async Task Invoke(IOwinContext context)
          {
              context.Response.Headers["Cache-Control"] = "no-cache, no-store, must-revalidate";
              context.Response.Headers["Pragma"] = "no-cache";
              context.Response.Headers["Expires"] = "0";
              await Next.Invoke(context);
          }
      }
      

      【讨论】:

      • 遇到了 IE11 积极缓存 ajax 响应的问题,这个中间件成功了。谢谢!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-10-01
      • 2021-03-14
      • 2018-08-29
      • 2017-08-01
      • 2012-12-31
      • 2020-05-05
      • 2021-08-17
      相关资源
      最近更新 更多