Angular ne met pas à jour la page avec le cache activé

j'ai fait un site web angulaire qui contient un "ajouter" et un "Supprimer" forme pour manipuler des données sur une table sur la même page.

lorsque je le teste localement ou avec Chrome Dev Console (cache désactivé), lorsque j'ajoute un nouvel élément ou en supprime un, la table se rafraîchit automatiquement. Lorsque je le teste sur le serveur de production (serveur IIS) de mon client, il ne fonctionne qu'avec la Console Chrome Dev ouverte. Sinon, ils doivent utiliser CTRL+F5 pour rafraîchir le cache et afficher les modifications sur le page.

C'est le code sur les composants:

  addProduct() {
    this._productsService.addProduct(this.addFormProductItem)
      .subscribe(v => {
        this._productsService.getProducts().subscribe( 
          products => {this.products = products, this.onChangeTable(this.config)}
      );
    });
    this.addmodalWindow.hide();
    return;
  } 


  onChangeTable(config: any, page: any = {
    page: this.page,
    itemsPerPage: this.itemsPerPage
  }): any {
    if (config.filtering) {
      Object.assign(this.config.filtering, config.filtering);
    }
    if (config.sorting) {
      Object.assign(this.config.sorting, config.sorting);
    }
    this.ng2TableData = this.products;
    this.length = this.ng2TableData.length;
    let filteredData = this.changeFilter(this.ng2TableData, this.config);
    let sortedData = this.changeSort(filteredData, this.config);
    this.rows = page && config.paging ? this.changePage(page, sortedData) : sortedData;
    this.length = sortedData.length;
  }

a mon avis, il s'agit soit d'une configuration de serveur, soit du code webpack. Cependant, je ne connais pas ce dernier et je l'ai simplement laissé tel quel sur le paquet de départ que j'ai utilisé.

j'ai créé une gist avec le webpack puisqu'il s'agit d'un long fichier

Edit 1: Après quelques recherches supplémentaires, j'ai essayé d'ajouter le suivant sur un site web.fichier de configuration sur le dossier racine de l'application.

<caching enabled="false" enableKernelCache="false">
      <profiles>
         <add extension=".css" policy="DontCache" kernelCachePolicy="DontCache" />
         <add extension=".html" policy="DontCache" kernelCachePolicy="DontCache" />
         <add extension=".js" policy="DontCache" kernelCachePolicy="DontCache" />
      </profiles>
</caching>

Cependant, j'ai toujours le même comportement. Ajout d'un élément avec la Console Dev fermée, il ne met pas à jour la table. Mais si j'ai la console dev ouverte et désactivé le cache, alors il le met à jour sans avoir besoin d'un rafraîchissement.

Edit 2: travailler sur la fenêtre Incognito ne règle pas le problème.

Edit 3: ajout de meta tags sur index.html ne règle pas le problème, encore.

<meta http-equiv="Cache-control" content="no-cache, no-store, must-revalidate">
<meta http-equiv="Pragma" content="no-cache">

Edit 4:

  getProducts() {
    return this._http.get(this.API + '/products/all')
      .map((response: Response) => <Product[]>response.json().products);
  }

  addProduct(product:Product) {
    if ( this._loggedInGuard.isLoggedIn() ) {
      let token = localStorage.getItem('my.token');
      let body = JSON.stringify(product);
      let headers = new Headers(
         { 'Content-Type': 'application/json',
         'Authorization': 'Bearer ' + token});
      return this._http
      .post(this.API + "/products/store", body, {headers: headers} )
      .map(res => res.json())
      .catch(this._responseService.catchBadResponse)
      .do(() => this._responseService.success('Success. You added a product!'));

    }  
  }

Modifier les 5

la seule solution que je peux trouver est de recharger la fenêtre à chaque fois que je fais une mise à jour sur les données avec location.reload(true). Mais encore une fois, cela ne fonctionne que sur Firefox et pas sur Chrome. Et je n'acceptera pas que vous devez abandonner la seule raison d'avoir une Seule Page App pour faire cela fonctionne.

24
demandé sur Red fx 2017-09-05 15:25:41

3 réponses

il y a des raisons précises pour lesquelles aucune des choses que vous avez essayées n'a été réparée.

tout D'abord, en utilisant le <caching> élément dans le web.config ne donne pas d'instructions à navigateur sur la façon de mettre en cache la réponse. Il est utilisé pour configurer comment L'IIS serveur cache la réponse afin qu'elle puisse être réutilisée dans des demandes futures. Ici est la documentation qui explique cela.

suivant, votre <meta> balises. Normalement, le contrôle du cache est effectué par des en-têtes http réels. Alors que vous pouvez utiliser <meta> balises pour définir les en-têtes qui ne sont pas du tout spécifiée dans votre tête de réponse http, ils seront outrepasser les en-têtes http qui sont déjà configurés. IIS a des valeurs par défaut pour la mise en cache dans les en-têtes de réponse, votre <meta> les balises ne sera pas réellement faire quoi que ce soit. <meta> les tags ne sont vraiment utiles que lorsque vous chargez sur un file:/// url.

afin d'atteindre de façon fiable ce que vous essayez pour ce faire, vous devez faire en sorte que le serveur envoie les en-têtes cache-control que vous voulez utiliser. Cela peut varier selon les navigateurs que vous essayez de prendre en charge, mais puisque vous utilisez angular, je pourrais supposer que vous prenez en charge les navigateurs modernes, ce qui est simple. Ce qui suit va désactiver la mise en cache pour tous les fichiers statiques dans votre site web, qui probablement n'est-ce pas exactement ce que vous voulez mais pourrait servir de guide.

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <location path=".">
    <system.webServer>
      <staticContent>
        <clientCache cacheControlMode="DisableCache" />
      </staticContent>
    </system.webServer>
  </location>
</configuration>

Toutefois, la première chose que vous devriez be doing examine les en-têtes de réponse actuels que L'IIS vous envoie! Cela peut être fait facilement en utilisant les outils de développement Chrome. Si vous voyez un Cache-Control: en-tête dans la réponse, ceci confirmera mon raisonnement sur Pourquoi votre <meta> les étiquettes ne fonctionnent pas.

si vous générez le HTML pour votre application angulaire pas avec un statique .le fichier html mais au lieu de le générer en utilisant ASP.NET, votre meilleur pari est d'ajouter du code dans votre controller qui définit le cache tête.

Response.Cache.SetCacheability(HttpCacheability.NoCache);

si vous voulez prendre en charge des navigateurs plus anciens ou brisés, il existe d'autres ressources qui décrivent les en-têtes supplémentaires que vous devrez ajouter, ce qui peut encore être fait en utilisant le web.config ou ASP.NET code. Je veux juste répéter: si vous avez encore des problèmes, assurez-vous que vous regardez les en-têtes de réponse envoyés par le serveur.

5
répondu Avi Cherry 2017-09-21 02:03:13

Pour ASP.NET pages que vous ne voulez pas mis en cache n'importe où,

HttpContext.Current.Response.Cache.SetCacheability
                            (HttpCacheability.Server);
HttpContext.Current.Response.Cache.SetNoStore();
Response.Cache.SetExpires(DateTime.Now); 
Response.Cache.SetValidUntilExpires(true); 

cela indique à tout serveur proxy de cache que seul le serveur est autorisé à mettre en cache la page et indique au serveur de ne pas le mettre en cache. Les deux dernières lignes de code demandent au navigateur de ne pas le mettre en cache. Le code ci-dessus mène à ces trois en-têtes:

 Cache-Control:no-cache, no-store
 Pragma:no-cache
 Expires:-1

vous pouvez aussi ajouter quelque chose d'unique à la chaîne de requête pour empêcher la mise en cache du navigateur.

.post(this.API + "/products/store?unique=milliseconds", body, {headers: headers} )
2
répondu earth_tom 2017-09-21 17:35:50

ajoutez un paramètre avec un tampon temps plein ou un id unique à chaque appel http que vous ne voulez pas mettre en cache. Fonctionne comme un champion. J'avais le même problème en utilisant des gabarits en angle. J'ai juste ajouté un intercepteur http et ajouté un horodatage à chaque appel et le problème a disparu.

1
répondu Lee Duckworth 2017-09-21 22:01:47