web-dev-qa-db-fra.com

Désactiver le cache nginx pour les fichiers JavaScript

Ok, j'abandonne presque tout ça, mais comment puis-je désactiver la mise en cache de Nginx pour les fichiers JavaScript? J'utilise un conteneur Docker avec Nginx. Lorsque je modifie maintenant quelque chose dans le fichier JavaScript, il me faut plusieurs rechargements jusqu'à ce que le nouveau fichier soit là.

Comment savoir si c'est Nginx et non le navigateur/menu fixe?

Navigateur: J'ai utilisé curl sur la ligne de commande pour simuler la demande et j'ai eu les mêmes problèmes. En outre, j'utilise un plug-in CacheKiller et le cache est désactivé dans Chrome Outils de développement.

Docker: Lorsque je me connecte à la bash du conteneur et que j'utilise cat après avoir modifié le fichier, j'obtiens immédiatement le résultat correct.

J'ai changé mon nginx.conf pour le sites-enabled à ceci (que j'ai trouvé dans un autre thread stackoverflow)

location ~* ^.+\.(jpg|jpeg|gif|png|ico|css|Zip|tgz|gz|rar|bz2|pdf|txt|tar|wav|bmp|rtf|js|flv|swf|xml|html|htm)$ {
    # clear all access_log directives for the current level
    access_log off;
    add_header Cache-Control no-cache;
    # set the Expires header to 31 December 2037 23:59:59 GMT, and the Cache-Control max-age to 10 years
    expires 1s;
}

Cependant, après la reconstruction des conteneurs (et en s'assurant qu'il est dans le conteneur avec cat), cela ne fonctionnait toujours pas. Ceci est la complète .conf

server {
    server_name app;
    root /var/www/app/web;

    # Redirect to blog
    location ~* ^/blog {
        proxy_set_header Accept-Encoding "";
        sub_filter 'https://testproject.wordpress.com/' '/blog/';
        sub_filter_once off;
        rewrite ^/blog/(.*) /$1 break;
        rewrite ^/blog / break;
        proxy_pass     https://testproject.wordpress.com;
    }

    # Serve index.html only for exact root URL
    location / {
        try_files $uri /app_dev.php$is_args$args;
    }

    location ~ ^/(app|app_dev|config)\.php(/|$) {
        fastcgi_pass php-upstream;
        fastcgi_split_path_info ^(.+\.php)(/.*)$;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param HTTPS off;
        # Prevents URIs that include the front controller. This will 404:
        # http://domain.tld/app_dev.php/some-path
        # Remove the internal directive to allow URIs like this
        internal;
    }

    location ~* ^.+\.(jpg|jpeg|gif|png|ico|css|Zip|tgz|gz|rar|bz2|pdf|txt|tar|wav|bmp|rtf|js|flv|swf|xml|html|htm)$ {
        # clear all access_log directives for the current level
        access_log off;
        add_header Cache-Control no-cache;
        # set the Expires header to 31 December 2037 23:59:59 GMT, and the Cache-Control max-age to 10 years
        expires 1s;
    }


    error_log /var/log/nginx/app_error.log;
    access_log /var/log/nginx/app_access.log;
}
29
Musterknabe

J'ai l'hôte virtuel nginx suivant (contenu statique) pour que le développement local désactive toute la mise en cache du navigateur:

server {
    listen 8080;
    server_name localhost;

    location / {
        root /your/site/public;
        index index.html;

        # kill cache
        add_header Last-Modified $date_gmt;
        add_header Cache-Control 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0';
        if_modified_since off;
        expires off;
        etag off;
    }
}

Aucun en-tête de cache envoyé:

$ curl -I http://localhost:8080
HTTP/1.1 200 OK
Server: nginx/1.12.1
Date: Mon, 24 Jul 2017 16:19:30 GMT
Content-Type: text/html
Content-Length: 2076
Connection: keep-alive
Last-Modified: Monday, 24-Jul-2017 16:19:30 GMT
Cache-Control: no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0
Accept-Ranges: bytes

Last-Modified est toujours l'heure actuelle.

56
Greg K

Les directives expires et add_header N'ont aucun impact sur la mise en cache des fichiers par NGINX. Celles-ci concernent uniquement ce que le navigateur voit.

Ce que vous voulez probablement à la place est:

location stuffyoudontwanttocache {
    # don't cache it
    proxy_no_cache 1;
    # even if cached, don't try to use it
    proxy_cache_bypass 1; 
}

Bien que d'habitude .js, etc. soit ce que vous cachez, vous devriez peut-être simplement désactiver la mise en cache entièrement?

19
Joshua DeWald

Ce que vous recherchez, c'est une directive simple comme:

location ~* \.(?:manifest|appcache|html?|xml|json)$ {
    expires -1;
}

Ce qui précède ne mettra pas en cache les extensions entre (). Vous pouvez configurer différentes directives pour différents types de fichiers.

8
Nitai

Rappelez-vous set sendfile off; ou les en-têtes de cache ne fonctionnent pas. J'utilise ce snippé:

location / {

        index index.php index.html index.htm;
        try_files $uri $uri/ =404; #.s. el /index.html para html5Mode de angular

        #.s. kill cache. use in dev
        sendfile off;
        add_header Last-Modified $date_gmt;
        add_header Cache-Control 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0';
        if_modified_since off;
        expires off;
        etag off;
        proxy_no_cache 1;
        proxy_cache_bypass 1; 
    }
3
Sergio Cano

J'ai l'hôte virtuel Nginx suivant (contenu statique) pour que le développement local désactive toute la mise en cache du navigateur:

    upstream testCom
        {
         server localhost:1338;
        }

    server
        {

            listen 80;
            server_name <your ip or domain>;
            location / {

            # proxy_cache   datacache;
            proxy_cache_key $scheme$Host$request_method$request_uri;
            proxy_cache_valid       200     60m;
            proxy_cache_min_uses    1;
            proxy_cache_use_stale   updating;

            proxy_pass_header Server;
            proxy_set_header Host $http_Host;
            proxy_redirect off;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Scheme $scheme;

            proxy_ignore_headers    Set-Cookie;

            userid          on;
            userid_name     __uid;
            userid_domain   <your ip or domain>;
            userid_path     /;
            userid_expires  max;
            userid_p3p      'policyref="/w3c/p3p.xml", CP="CUR ADM OUR NOR STA NID"';


            add_header Last-Modified $date_gmt;
            add_header Cache-Control 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0';
            if_modified_since off;
            expires off;
            etag off;

            proxy_pass http://testCom;
        }
    }
3
Ashish Gupta

Je sais que cette question est un peu ancienne, mais je suggérerais d'utiliser un hachage de cachebraking dans l'URL du javascript. Cela fonctionne parfaitement en production ainsi que pendant le développement car vous pouvez avoir des temps de cache infinis et des mises à jour instantanées lorsque des modifications sont apportées.

Supposons que vous avez un fichier javascript / js/script.min.js, mais dans le fichier de référencement html/php, vous n'utilisez pas le chemin réel, mais:

<script src="/js/script.<?php echo md5(filemtime('/js/script.min.js')); ?>.min.js"></script>

Ainsi, chaque fois que le fichier est modifié, le navigateur obtient une URL différente, ce qui signifie qu’il ne peut pas être mis en cache, que ce soit localement ou sur un proxy intermédiaire.

Pour que cela fonctionne, vous devez demander à nginx de réécrire toute demande dans /js/script.[0-9a-f]{32Buch.min.js dans le nom de fichier original. Dans mon cas, j'utilise la directive suivante (pour CSS également):

location ~* \.(css|js)$ {
                expires max;
                add_header Pragma public;
                etag off;
                add_header Cache-Control "public";
                add_header Last-Modified "";
                rewrite  "^/(.*)\/(style|script)\.min\.([\d\w]{32})\.(js|css)$" /$1/$2.min.$4 break;
        }

Je suppose que l’appel filemtime ne nécessite même pas d’accès disque sur le serveur, comme il se doit dans le cache de fichiers de Linux. Si vous avez des doutes ou des fichiers HTML statiques, vous pouvez également utiliser une valeur aléatoire fixe (ou un hachage incrémentielle ou de contenu) qui est mise à jour lorsque votre préprocesseur javascript/css est terminée ou laissée par l'un de vos crochets git.

En théorie, vous pouvez également utiliser un cachebreaker en tant que paramètre factice (comme /js/script.min.js?cachebreak=0123456789abcfef), mais le fichier n'est pas mis en cache au moins par certains mandataires à cause du "? ".

0
Florian