web-dev-qa-db-fra.com

L'attribut ResponseCache ne met pas en cache les données côté client

Dans l'application ASP.NET Core, j'ai une méthode d'action qui renvoie des données. Je voulais mettre en cache ces données côté client . Donc, basé sur la documentation ici i peut utiliser l'attribut ResponseCache sur la méthode d'action. Cet attribut ajoute l'en-tête Cache-Control en réponse.

La mise en cache des réponses consiste à spécifier des en-têtes liés au cache sur les réponses HTTP Effectuées par les actions ASP.NET Core MVC. Ces en-têtes indiquent comment Vous voulez que les machines clientes et intermédiaires (proxy) cachent les réponses À certaines demandes (le cas échéant). Cela peut réduire le nombre de Demandes adressées par le client ou le proxy au serveur Web, car les futures demandes Relatives à la même action pourraient être traitées à partir de la mémoire cache de Du client ou du proxy.

également 

La mise en cache des réponses ne met pas les réponses en cache sur le serveur Web. Il Diffère de la mise en cache de sortie, qui mettrait en cache les réponses en mémoire sur Le serveur dans les versions antérieures d'ASP.NET et ASP.NET MVC.

Voilà comment ma méthode d'action ressemble

public class LookupController : Controller
{
    [HttpGet]
    [ResponseCache(Duration = 120)]
    public IEnumerable<StateProvinceLookupModel> GetStateProvinces()
    {
        return _domain.GetStateProvinces();
    }
}

Ensuite, j’appelle la méthode à l’aide de browser comme http: // localhost: 40004/lookup/getstateprovinces Voici les en-têtes de requête et de réponse

 enter image description here

Notez que Response Headers a Cache-Control: public,max-age-120 comme prévu. Toutefois, si vous actualisez la page à l'aide de F5 (avant 120 secondes), le point d'arrêt du débogueur dans la méthode d'action GetStateProvince est toujours actif. Cela signifie que ce n'est pas cahing les données côté client.

Dois-je faire quelque chose d'autre pour activer la mise en cache côté client?

Mise à jour J'ai essayé d'utiliser IE, Chrome et aussi POSTMAN sans succès. Chaque fois que je tape l'URL dans la barre d'adresse ou que je clique sur Actualiser, le client (navigateur ou facteur) lance un appel à la méthode d'action.

13
LP13

En réalité ResponseCache attribut fonctionne comme prévu.
La différence est que la réponse est mise en cache si vous naviguez dans les pages de votre site Web ( cas 1 ), ou utilisez les boutons Précédent/Suivant ( pas lors de l'actualisation de la page ) . 

Comme exemple de cas 1 , j'ai les éléments suivants: 

Comme vous le verrez dans l'article Response Caching dans ASP.Net Core 1.1 , vous indiquez ce qui suit: 

Au cours d'une session de navigateur, lorsque vous parcourez plusieurs pages du site Web ou que vous utilisez les boutons Précédent et Suivant pour visiter les pages, le contenu est diffusé à partir du cache du navigateur local (s'il n'a pas expiré).
Mais lorsque la page est actualisée via F5 , la requête sera adressée au serveur et le contenu de la page sera actualisé. Vous pouvez le vérifier via l'actualisation de la page de contact à l'aide de F5.
Ainsi, lorsque vous appuyez sur F5, la valeur d'expiration de la mise en cache de la réponse n'a aucun rôle à jouer pour servir le contenu. Vous devriez voir 200 réponse pour la demande de contact.

Références:
[1]. Exemple de mise en cache de réponses ASP.NET Core
[2]. Exemple d'attribut ResponseCache
[3]: Comment contrôler la mise en cache des pages Web sur tous les navigateurs?

9
Michael

En résumé, l'utilisation de l'attribut ResponseCache comme suit suffit pour que la mise en cache côté client basée sur l'expiration fonctionne dans un tout nouveau projet de base par défaut dotnet (y compris les méthodes async):

[HttpGet]
[ResponseCache(Duration = 120)]
public IEnumerable<StateProvinceLookupModel> GetStateProvinces()
{
    return _domain.GetStateProvinces();
}

Cela fonctionne correctement dans la capture d'écran ci-dessus, car le Cache-Control: public,max-age=120 y est visible. Dans la plupart des cas, les navigateurs n'enverront pas les requêtes suivantes avant l'expiration (c'est-à-dire pendant les 120 prochaines secondes ou les 2 prochaines minutes), mais il s'agit d'une décision du navigateur (ou d'un autre client).

Si la demande est _ envoyée malgré tout, une configuration de middleware ou de serveur écrasant les en-têtes de réponse ou votre client ignore la directive de mise en cache. Dans la capture d'écran ci-dessus, le client ignore la mise en cache, car l'en-tête de contrôle du cache est présent.

Cas courants dans lesquels le cache du client est ignoré et la demande envoyée:

  • Chrome empêche tout type de mise en cache lors de l'utilisation de HTTPS sans certificat (ou un certificat non valide, il s'agit souvent d'un développement local. Veillez donc à utiliser HTTP lorsque vous testez votre cache ou faites confiance à un certificat auto-signé)
  • La plupart des outils de développement de navigateur désactivent la mise en cache par défaut à l'ouverture, cela peut être désactivé
    • Les navigateurs envoient généralement des en-têtes supplémentaires, Chrome envoie Cache-Control: no-cache
  • Actualiser directement (par exemple, F5) indiquera à la plupart des navigateurs de ne pas utiliser de mémoire cache et de faire la demande, quel que soit leur âge.
    • Les navigateurs envoient généralement des en-têtes supplémentaires, Chrome envoie Cache-Control: max-age=0 (visible sur la capture d'écran).
  • Postman envoie l'en-tête Cache-Control: no-cache, ce qui lui permet de contourner le cache local, ce qui entraîne l'envoi de demandes. vous pouvez le désactiver à partir de la boîte de dialogue de configuration, auquel cas les demandes ne seront plus envoyées avec la configuration de cache client ci-dessus

À ce stade, nous sommes au-delà de la mise en cache du client basée sur l'expiration, et le serveur recevra recevra la demande d'une manière ou d'une autre, et une autre couche de mise en cache se produira: vous pouvez faire en sorte que le serveur réponde avec un code 304 Not Modified (qui Il appartient ensuite au client d’interpréter à sa guise) ou d’utiliser un cache côté serveur et de répondre avec le contenu complet. Sinon, vous ne pouvez plus utiliser la mise en cache ultérieure et effectuer à nouveau le traitement complet de la demande sur le serveur.


Remarque: l'attribut ResponseCache ne doit pas être confondu avec le middleware services.AddResponseCaching() & app.UseResponseCaching() dans la configuration de démarrage, car il s'agit d'une mise en cache côté serveur (qui utilise par défaut un cache en mémoire lors de l'utilisation du middleware). Le middleware est non requis pour que la mise en cache du client fonctionne, l'attribut suffit à lui seul.

0
John Weisz