IIS/ASP.NET使用cache-control响应:对所有请求都是private

Mar*_*ius 14 asp.net iis asp.net-mvc caching

为什么ASP.NET的所有响应都包含Cache-Control: private?即使是404响应?IIS中是否有设置此默认值的东西,有没有办法配置它?或者ASP.NET中有什么设置这个?

对于动态内容(即所有MVC结果),我不希望它被浏览器缓存,因为它是动态的,可以随时更改.静态内容托管在CDN上,因此IIS不提供服务.

编辑:

为了澄清,我非常理解什么Cache-Control: private是,之间的区别private,public,no-store,等以及如何/何时使用它们.我的问题是Cache-Control: privateIIS/ASP.NET默认添加的原因以及如何防止默认情况下添加它.据我所知,它可以被缓存动态页面是有用的,但在我的应用程序,我希望缓存动态页面/响应.例如,我不想XHR JSON响应被缓存,因为它们含有动态内容.不幸的是,服务器会Cache-Control: private自动添加所有响应,因此我必须在任何地方手动覆盖它.

如何重现:使用MVC项目打开visual studio并创建一个新的ASP.NET框架(是的,框架,不是Core.我们无法将系统迁移到核心).现在在IIS Express中启动项目(只需按下播放按钮),然后在浏览器中使用F12 devtools查看http响应.你会看到它包含Cache-Control: private.我的问题是,添加此标题的是什么,以及如何防止默认情况下添加它?

在此输入图像描述

Ani*_*nil 6

把我的位添加到上面的答案中;

1. http缓存标头attrubute Cache-Control:IIS/ASP.NET默认添加private?

缓存请求指令

标准Cache-Control指令,可由客户端在HTTP请求中使用.

    Cache-Control: max-age=<seconds>
    Cache-Control: max-stale[=<seconds>]
    Cache-Control: min-fresh=<seconds>
    Cache-Control: no-cache 
    Cache-Control: no-store
    Cache-Control: no-transform
    Cache-Control: only-if-cached
Run Code Online (Sandbox Code Playgroud)

缓存响应指令

标准Cache-Control指令,可由服务器在HTTP响应中使用.

    Cache-Control: must-revalidate
    Cache-Control: no-cache
    Cache-Control: no-store
    Cache-Control: no-transform
    Cache-Control: public
    Cache-Control: private
    Cache-Control: proxy-revalidate
    Cache-Control: max-age=<seconds>
    Cache-Control: s-maxage=<seconds>
Run Code Online (Sandbox Code Playgroud)

IIS使用安全且更明显/有用的默认设置,这恰好是私有的

2.如何防止默认添加?

IIS/asp.net允许这从它被引入像一天被配置,ref1用,ref2用,REF3,REF4

System.Web命名空间

System.Web命名空间提供了启用浏览器 - 服务器通信的类和接口.此命名空间包括System.Web.HttpRequest类,该类提供有关当前HTTP请求的大量信息; System.Web.HttpResponse类,它管理客户端的HTTP输出; 和System.Web.HttpServerUtility类,它提供对服务器端实用程序和进程的访问.System.Web还包括用于cookie操作,文件传输,异常信息和输出缓存控制的类.

protected void Application_BeginRequest()
{
  Context.Response.Cache.SetCacheability(HttpCacheability.NoCache);
}
Run Code Online (Sandbox Code Playgroud)


Cod*_*ler 5

TL; DR

  1. 默认情况下,动态 ASP.NET 页面不使用缓存。您需要努力在 ASP.NET 中启用缓存。
  2. “Cache-Control: private”标头的存在并不意味着页面的缓存版本将用于重复请求。

--

有一个非常简单的测试来验证上述陈述。创建一个返回当前时间的操作:

public ActionResult Index()
{
    ViewBag.CurrTime = DateTime.Now.ToString("T");
    return View();
}
Run Code Online (Sandbox Code Playgroud)

看法:

@{
    ViewBag.Title = "Home Page";
}

<h1>@ViewBag.CurrTime</h1>
Run Code Online (Sandbox Code Playgroud)

如果您在浏览器中刷新此类页面,您将看到每个请求的最新时间:

在此输入图像描述

在此输入图像描述

可以在 ASP.NET MVC 中使用缓存,但您应该付出一些努力来启用它。有关详细信息,请参阅这篇文章

如果尽管如此,您仍然出于某种原因想要排除缓存的任何可能性,您可以通过设置特定的 HTTP 标头来实现。有一个很好的答案列出了应该设置哪些标头:

Cache-Control: no-cache, no-store, must-revalidate
Pragma: no-cache
Expires: 0
Run Code Online (Sandbox Code Playgroud)

您可以使用操作过滤器在每个 ASP.NET 响应中设置这些标头:

public class CachingHeadersFilterAttribute : ActionFilterAttribute
{
    public override void OnResultExecuted(ResultExecutedContext filterContext)
    {
        var response = filterContext.HttpContext.Response;

        response.Cache.SetCacheability(HttpCacheability.NoCache);
        response.Cache.AppendCacheExtension("no-store, must-revalidate");
        response.AppendHeader("Pragma", "no-cache");
        response.AppendHeader("Expires", "0");

        base.OnResultExecuted(filterContext);
    }
}
Run Code Online (Sandbox Code Playgroud)

在 FilterConfig.cs 中(在 ASP.NET MVC 模板中自动创建):

public class FilterConfig
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new HandleErrorAttribute());
        filters.Add(new CachingHeadersFilterAttribute());
    }
}
Run Code Online (Sandbox Code Playgroud)

以下是响应的结果标头:

HTTP/1.1 200 OK
Cache-Control: no-cache, no-store, must-revalidate
Pragma: no-cache
Content-Type: text/html; charset=utf-8
Expires: -1
Vary: Accept-Encoding
Server: Microsoft-IIS/10.0
X-AspNetMvc-Version: 5.2
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?RDpcRHJvcGJveFxwcm9nXFN0YWNrT3ZlcmZsb3dcUTQ3MjI0NTYxQ2FjaGVcUTQ3MjI0NTYxQ2FjaGU=?=
X-Powered-By: ASP.NET
Date: Mon, 13 Nov 2017 17:44:33 GMT
Content-Length: 837
Run Code Online (Sandbox Code Playgroud)

如您所见,没有“Cache-Control: private”标头。

但同样,我不认为您应该将此类过滤器添加到您的应用程序中。