IIS/ASP.NET以缓存控制响应:所有请求专用

wgeznvg7  于 2022-11-12  发布在  .NET
关注(0)|答案(7)|浏览(142)

为什么所有来自ASP.NET的响应都包含Cache-Control: private?甚至是404响应?IIS中是否有设置此默认值的程序,以及是否有配置它的方法?或者ASP.NET中是否有设置此默认值的程序?
对于动态内容(即所有MVC结果),我不希望浏览器缓存它,因为它是动态的,可以随时更改。静态内容托管在CDN上,因此不由IIS提供服务。

编辑:

澄清一下,我非常清楚Cache-Control: private是什么,privatepublicno-store等之间的区别,以及如何/何时使用它们。我的问题是为什么IIS/ASP.NET默认添加Cache-Control: private,以及如何防止默认添加它。我知道缓存动态页 * 可能 * 很有用,但在我的应用程序中,我 * 不 * 希望缓存动态页面/响应。例如,我不希望缓存XHR JSON响应,因为它们包含动态内容。不幸的是,服务器会自动将Cache-Control: private添加到所有响应中,因此我必须在所有地方手动覆盖它。

**如何重现:**打开visual studio并创建一个新的ASP.NET Framework(是的,是框架,不是核心。我们还不能将系统迁移到核心)解决方案和一个MVC项目。现在在IIS Express中启动该项目(只需按下播放按钮),并在浏览器中使用F12 devtools查看http响应。您将看到它包含Cache-Control: private。我的问题是,是什么添加了这个头,以及如何防止它被添加 * 默认情况下 *?

jslywgbw

jslywgbw1#

在社区给出的伟大答案中加入我的一点;

1. http缓存头属性Cache-Control:默认情况下,IIS/ASP.NET会添加private?
缓存请求指令

客户端可在HTTP请求中使用的标准Cache-Control指令。

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

缓存响应指令

服务器可在HTTP响应中使用的标准Cache-Control指令。

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>

IIS使用安全且更明显/有用的默认值,它恰好是私有的
2.如何防止默认添加?

IIS/asp.net允许从引入之日起就进行配置,如thisref1ref2ref3ref4
System.Web Namespace
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);
}
vvppvyoh

vvppvyoh2#

TL; DR
1.默认情况下,动态ASP.NET页不使用缓存。您需要努力在ASP.NET中启用缓存。
1.是否存在“缓存控制:private“头并不意味着页面的缓存版本将用于重复的请求。

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

public ActionResult Index()
{
    ViewBag.CurrTime = DateTime.Now.ToString("T");
    return View();
}

查看方式:

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

<h1>@ViewBag.CurrTime</h1>

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

在ASP.NET MVC中可以使用缓存,但是您应该努力启用它。有关详细信息,请参阅此article
尽管如此,如果出于某种原因,你仍然想排除缓存的可能性,你可以通过设置特定的HTTP头来做到这一点。有一个很棒的SO answer列出了应该设置哪些头:

Cache-Control: no-cache, no-store, must-revalidate
Pragma: no-cache
Expires: 0

您可以使用操作筛选器在每个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);
    }
}

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

public class FilterConfig
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new HandleErrorAttribute());
        filters.Add(new CachingHeadersFilterAttribute());
    }
}

以下是来自响应的结果标头:

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

如您所见,没有“缓存控制:private'标头。
但是,同样,我看不出有什么理由要在应用程序中添加这样的过滤器。

n3schb8v

n3schb8v3#

什么添加了这个报头?
IIS 7和更高版本(* 包含在默认安装中 *)将其作为与缓存相关的HTTP头之一发送到Web客户端。
以及如何防止默认情况下添加它?
我将根据您的问题介绍两种禁用缓存机制的方法(服务器端方法和客户端方法),重点介绍服务器端:

服务器端方法

Internet信息服务(IIS)管理器中按照以下步骤更改Cache-Control值(* 虽然我认为这适用于静态内容 ):
1.在连接窗格中,转到要 * 禁用缓存 * 的 * 站点 应用程序 * 或 * 目录
1.在主页窗格中,双击
HTTP Response Headers
1.单击
操作窗格中的Set Common Headers...。
1.* 选中
expire Web content**框,选择在特定时间间隔后或在特定时间过期的选项,然后单击“确定”。
一种方法是如下注解控制器,这是非常强大的,并且响应头包含Cache-Control: publicmax-age=0头:

[OutputCache(Duration = 0)]
public class SomeController : Controller  {

}

您也可以在应用程序的 Web.config 档案中定义快取设定档,并在设定档中包含durationvaryByParam设定:

<caching>
  <outputCacheSettings>
    <outputCacheProfiles>
      <add name="nocache" duration="0" 
        varyByParam="none" />
    </outputCacheProfiles>
  </outputCacheSettings>
</caching>

然后使用它由[OutputCache CacheProfile="nocache"]前/控制器动作。

**请注意,*web.config 文件(如下)中有一个配置,不会阻止缓存。相反, 它只是指示不应应用任何类型的缓存机制 *。通过禁用输出缓存,我们可以获得www.example.com MVC使用的默认缓存头ASP.net,该头福尔斯退到Cache-Control: private,从而再次打开浏览器缓存请求的可能性。

<caching>
    <outputCache enableOutputCache="false" />
</caching>

客户端方法

在js请求中使用cache: false,例如:

$.ajax({
    type: 'GET',
    cache: false,
    url: '/nation',
    ...
});

如欲了解更多信息,请访问:

ht4b089n

ht4b089n4#

来自RickNZ的答案,从https://forums.asp.net复制
Cache-Control private表示客户端可以缓存页面,但要受其过期日期的限制。过期日期可以通过Cache-Control提供:在默认情况下,页面被设置为立即过期,这意味着它不会被缓存。
缓存控制的目的之一:private实际上是告诉中间代理它们不应该缓存页面。
顺便说一句,仅仅因为页面是动态的并不意味着它永远不应该被缓存。在很多情况下缓存动态页面是合适的。你不仅可以在客户端缓存,还可以在代理和服务器的输出缓存中缓存。
更多信息:
IIS 7.0 - IIS adding "private" to cache-control, where is that coming from
Private vs Public in Cache-Control
https://msdn.microsoft.com/en-us/library/ms524721(v=vs.90).aspx
https://msdn.microsoft.com/en-us/library/system.web.httpcacheability(VS.71).aspx
https://forums.asp.net/t/1443346.aspx?Cache+control+private+
https://forums.asp.net/t/2052325.aspx?Remove+the+private+value+from+the+Cache+Control+in+the+Response+Header

lp0sw83n

lp0sw83n5#

默认情况下,Cache-Control: private标头由框架添加到响应中。
https://learn.microsoft.com/en-us/dotnet/api/system.web.configuration.httpruntimesection.sendcachecontrolheader?view=netframework-4.8

定义

获取或设置一个值,该值指示默认情况下输出缓存模块是否发送cache-control:private头。
...

备注

HttpResponse类别会检查HttpRuntimeSection.SendCacheControlHeader属性和OutputCacheSection.SendCacheControlHeader属性,以判断是否要在HTTP回应中传送cache-control:private信头。如果其中一个属性设定为false,则不会传送信头。如果快取控制信头设定为private,则客户端不会在共用快取中快取回应。
在HttpRuntimeSection类中提供对SendCacheControlHeader属性的支持是为了与旧版应用程序兼容;此属性在.NET Framework 2.0版中已过时。有关详细信息,请参见OutputCacheSection类。
要防止添加Cache-Control: private标头,只需禁用OutputCacheSection.SendCacheControlHeader属性,该属性默认为true
https://learn.microsoft.com/en-us/dotnet/api/system.web.configuration.outputcachesection.sendcachecontrolheader?view=netframework-4.8#system-web-configuration-outputcachesection-sendcachecontrolheader

属性值

如果允许发送cache-control:private报头,则为true;否则为false。预设值为true
示例web.config

<configuration>
  <system.web>
    <caching>
      <outputCache sendCacheControlHeader="false" />
    </caching>
  </system.web>
</configuration>
p4rjhz4m

p4rjhz4m6#

默认值在System.Web.HttpResponse.CacheControl中指定:

/// <devdoc>
        ///    <para>
        ///       Provided for ASP compatiblility. Use the <see cref='System.Web.HttpResponse.Cache'/>
        ///       property instead.
        ///    </para>
        /// </devdoc>
        public string CacheControl {
            get {
                if (_cacheControl == null) {
                    // the default
                    return "private";
                }

                return _cacheControl;
            }

虽然你可以通过(全局)过滤器覆盖头,但这对由身份验证/授权引起的错误页面不起作用。幸运的是,每个请求都有一个很好的入口点,允许你覆盖这个默认值:

// In Global.asax.cs:
        protected void Application_BeginRequest()
        {
            Context.Response.CacheControl = "no-cache";
        }

此外,当出现错误,YSOD(黄色错误页面)通过ReportRuntimeError呈现时,框架将调用ClearHeaders,并且您的自定义缓存控制设置将被覆盖。

nuypyhwy

nuypyhwy7#

解决问题:
您将看到它包含Cache-Control:private。我的问题是,什么添加了这个头,我如何防止它被默认添加?
简短的回答是:正如其他人所指出的,这是IIS(7+)的默认设置。
更充分地回答:如果您希望控制或修改用于缓存HTTP请求的默认设置Cache-Control: private,服务器端。
这将取决于您运行的IIS的具体版本,以及您希望修改的具体程度。一般来说,您可以使用HTTP响应头界面(在IIS管理器=〉功能视图- IIS中)进行修改。
如果您只想停用网站或应用程序的快取:
1.转到IIS管理器
1.选择所需的站点/应用程序
1.在功能视图中,选择HTTP响应报头
1.在执行窗格中,按一下:设置公用标题
1.选中使Web内容过期
1.设置为:立即
1.好的
或者,从命令行执行以下操作:

appcmd.exe set config  "Default Web Site" -section:system.webServer/staticContent /clientCache.cacheControlMode:"DisableCache"

有关详细信息和细节,请查看:
https://learn.microsoft.com/en-us/iis/configuration/system.webserver/staticcontent/clientcache
希望这是你要找的,干杯。

相关问题