web-dev-qa-db-fra.com

IIS / ASP.NET répond avec cache-control: privé pour toutes les demandes

Pourquoi toutes les réponses d'ASP.NET contiennent Cache-Control: private? Même une réponse 404? Y a-t-il quelque chose dans IIS qui définit cette valeur par défaut, et existe-t-il un moyen de la configurer? Ou y a-t-il quelque chose dans ASP.NET qui définit cela?

Pour le contenu dynamique (c'est-à-dire tous les résultats MVC), je ne voudrais pas qu'il soit mis en cache par le navigateur, car il est dynamique et peut changer à tout moment. Le contenu statique est hébergé sur un CDN, il n'est donc pas servi par IIS.

Modifier:

Pour clarifier, je comprends très bien ce que Cache-Control: private est, la différence entre private, public, no-store, etc et comment/quand les utiliser. La question que je me pose est pourquoi Cache-Control: private est ajouté par défaut par IIS/ASP.NET et comment l'empêcher d'être ajouté par défaut. Je comprends qu'il peut être utile pour mettre en cache des pages dynamiques, mais dans mon application, je pas je veux mettre en cache des pages/réponses dynamiques. Par exemple, je ne veux pas que les réponses XHR JSON soient mises en cache, car elles contiennent du contenu dynamique. Malheureusement, le serveur ajoute Cache-Control: private à toutes les réponses automatiquement, je dois donc la remplacer manuellement partout.

Comment reproduire: Ouvrez Visual Studio et créez un nouveau Framework ASP.NET (oui, framework, non pas Core. Nous ne sommes pas en mesure de migrer notre système au cœur de la solution) avec un projet MVC. Maintenant, lancez le projet dans IIS Express (appuyez simplement sur le bouton de lecture) et utilisez F12 devtools dans le navigateur pour consulter la réponse http. Vous verrez qu'il contient Cache-Control: private. Ma question est, qu'est-ce qui ajoute cet en-tête, et comment puis-je l'empêcher d'être ajouté par défaut?

enter image description here

14
Marius

Ajout de mon bit aux grandes réponses, données par la communauté;

1. http mise en cache de l'en-tête attrubute Cache-Control : private est ajouté par défaut par IIS/ASP.NET?

Directives de demande de cache

Directives de contrôle du cache standard pouvant être utilisées par le client dans une requête 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

Directives de réponse du cache

Directives de contrôle du cache standard pouvant être utilisées par le serveur dans une réponse 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>

IIS utilise celui sécurisé et le plus évident/utile par défaut, qui se trouve être privé

2. comment l'empêcher d'être ajouté par défaut?

IIS/asp.net permet de le configurer à partir du jour où il a été introduit comme this , ref1 , ref2 , ref , ref4 et

Espace de noms System.Web

L'espace de noms System.Web fournit des classes et des interfaces qui permettent la communication navigateur-serveur. Cet espace de noms inclut la classe System.Web.HttpRequest, qui fournit des informations détaillées sur la requête HTTP actuelle; la classe System.Web.HttpResponse, qui gère la sortie HTTP vers le client; et la classe System.Web.HttpServerUtility, qui donne accès aux utilitaires et processus côté serveur. System.Web comprend également des classes pour la manipulation des cookies, le transfert de fichiers, les informations d'exception et le contrôle du cache de sortie.

protected void Application_BeginRequest()
{
  Context.Response.Cache.SetCacheability(HttpCacheability.NoCache);
}
6
Anil

Une réponse de RickNZ , copiée de https://forums.asp.net

Cache-Control private indique qu'il est OK pour le client de mettre en cache la page, sous réserve de sa date d'expiration. L'expiration peut être fournie soit avec Cache-Control: max-age, soit avec un en-tête HTTP Expires. Dans le cas par défaut, la page est définie pour expirer immédiatement, ce qui signifie qu'elle ne sera pas mise en cache.

L'un des objectifs de Cache-Control: private est vraiment de dire aux mandataires intermédiaires qu'ils ne doivent pas mettre en cache la page.

BTW, ce n'est pas parce qu'une page est dynamique qu'elle ne doit jamais être mise en cache. Il existe de nombreux cas où la mise en cache d'une page dynamique est appropriée. Vous pouvez mettre en cache non seulement sur le client, mais également dans les proxys et dans le cache de sortie du serveur.

Plus d'informations:

IIS 7.0 - IIS ajoutant "privé" au cache-contrôle, d'où vient-il

Privé vs Public dans 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+fr++the+Cache+Control+in+the+Response+Header

3
VDWWD

qu'est-ce qui ajoute cet en-tête?

Le IIS 7 et versions ultérieures ( inclus dans l'installation par défaut) l'envoie aux clients Web comme l'un des en-têtes HTTP liés au cache.

et comment puis-je empêcher son ajout par défaut?

Je décris deux façons de désactiver le mécanisme de cache (approche côté serveur et approche côté client) en mettant l'accent sur le côté serveur en fonction de votre question:

Approche côté serveur

Suivez ces étapes Dans le Gestionnaire des services Internet (IIS) pour modifier Cache-Control value ( alors que je pense que cela fonctionne pour les contenus statiques):

  1. Dans le volet Connexions , accédez au site, application, ou = répertoire pour lequel vous souhaitez désactiver la mise en cache.
  2. Dans le volet Accueil , double-cliquez sur En-têtes de réponse HTTP.
  3. Cliquez sur Définir les en-têtes communs ... dans les actions volet.
  4. Vérifiez la case à expirer le contenu Web, sélectionnez l'option pour expirer après un certain intervalle ou à une heure spécifique, puis cliquez sur OK.

Une façon consiste à annoter votre contrôleur comme suit, ce qui est assez puissant et les en-têtes de réponse contiennent un Cache-Control: public, max-age=0 entête.:

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

}

Vous pouvez également définir un profil de cache dans le fichier Web.config de votre application et dans le profil, inclure les paramètres duration et varyByParam:

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

Ensuite, utilisez-le par le [OutputCache CacheProfile="nocache"] avant l'action/le contrôleur.

Notez que il y a une configuration dans le fichier web.config (suivant) qui n'empêchera pas la mise en cache . Au lieu de cela cela indique simplement qu'aucun type de mécanisme de mise en cache ne doit être appliqué. En désactivant simplement le cache de sortie, nous obtenons les en-têtes de cache par défaut utilisés par ASP.net MVC qui reviennent à Cache-Control: private, ouvrant ainsi à nouveau au navigateur la possibilité de mettre en cache les requêtes.

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

Approche côté client

En utilisant cache: false dans votre requête js comme:

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

Pour des informations supplémentaires , visitez:

2

TL; DR

  1. La mise en cache n'est pas utilisée par défaut pour les pages ASP.NET dynamiques. Vous devez faire des efforts pour activer la mise en cache dans ASP.NET.
  2. La présence de l'en-tête "Cache-Control: private" ne signifie pas du tout que la version en cache de la page sera utilisée lors de requêtes répétées.

-

Il existe un test très simple pour valider les déclarations ci-dessus. Créez une action qui renvoie l'heure actuelle:

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

Vue:

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

<h1>@ViewBag.CurrTime</h1>

Si vous actualisez une telle page dans un navigateur, vous verrez du temps frais à chaque demande:

enter image description here

enter image description here

Il est possible d'utiliser la mise en cache avec ASP.NET MVC mais vous devez faire quelques efforts pour l'activer. Voir ceci article pour plus de détails.

Si malgré cela vous voulez toujours pour une raison quelconque exclure toute possibilité de mise en cache, vous pouvez le faire en définissant des en-têtes HTTP spécifiques. Il y a un grand réponse SO qui répertorie les en-têtes à définir:

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

Vous pouvez utiliser un filtre d'action pour définir ces en-têtes dans chaque réponse 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);
    }
}

Dans FilterConfig.cs (créé automatiquement dans le modèle ASP.NET MVC):

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

Voici les en-têtes de résultat de la réponse:

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

Comme vous le voyez, il n'y a pas d'en-tête "Cache-Control: private".

Mais encore une fois, je ne vois pas pourquoi vous devriez ajouter un tel filtre à votre application.

2
CodeFuller

Répondre à la question:

Vous verrez qu'il contient Cache-Control: private. Ma question est de savoir ce qui ajoute cet en-tête et comment puis-je empêcher son ajout par défaut?

La réponse courte est: comme d'autres l'ont noté, il s'agit d'un paramètre par défaut d'IIS (7+).

Pour répondre plus complètement: Si vous souhaitez contrôler ou modifier le paramètre par défaut Cache-Control: private pour la mise en cache des requêtes HTTP, côté serveur.

Cela dépendra de la version spécifique de IIS que vous exécutez et du degré de précision que vous souhaitez apporter à votre modification. De manière générale, vous pouvez toutefois le faire en utilisant votre Interface des en-têtes de réponse HTTP (dans Gestionnaire IIS => Caractéristiques vue - IIS)

Si vous souhaitez simplement désactiver la mise en cache pour un site Web ou une application:

  1. aller à Gestionnaire IIS
  2. Sélectionnez le site/l'application souhaitée
  3. dans la vue des fonctionnalités, sélectionnez En-têtes de réponse HTTP :
  4. Dans le volet Actions, cliquez sur: Définir les en-têtes communs
  5. check Expiration du contenu Web
  6. Réglez sur: immédiatement
  7. D'accord

alternativement, à partir de votre ligne de commande:

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

Pour des informations détaillées et des détails, veuillez vérifier:

https://docs.Microsoft.com/en-us/iis/configuration/system.webserver/staticcontent/clientcache

J'espère que c'est ce que vous cherchiez, cheers.

1
DaniDev