Nginx-cache uitschakelen voor JavaScript-bestanden

Ok, ik geef het bijna op, maar hoe kan ik de caching van Nginx voor JavaScript-bestanden uitschakelen? Ik gebruik een docker-container met Nginx. Als ik nu iets in het JavaScript-bestand verander, moet ik meerdere keren opnieuw laden totdat het nieuwe bestand er is.

Hoe weet ik dat het Nginx is en niet de browser/docker?

Browser: ik gebruikte curlop de opdrachtregel om het verzoek te simuleren en had dezelfde problemen. Ik gebruik ook een CacheKiller-plug-in en heb cache uitgeschakeld in Chrome Dev Tools.

Docker: wanneer ik verbinding maak met de bash van de container en catgebruik nadat ik het bestand heb gewijzigd, krijg ik onmiddellijk het juiste resultaat.

Ik heb mijn nginx.confvoor de sites-enabledhierin gewijzigd (die ik vond in een andere stackoverflow-thread)

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;
}

Na het opnieuw opbouwen van de containers (en ervoor zorgen dat het in de container met catzit), werkte het echter nog steeds niet. Dit hier is de volledige .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;
}

Antwoord 1, autoriteit 100%

Ik heb de volgende virtuele nginx-host (statische inhoud) voor lokaal ontwikkelingswerk om alle browsercaching uit te schakelen:

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';
        if_modified_since off;
        expires off;
        etag off;
    }
}

Geen cache-headers verzonden:

$ 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
Accept-Ranges: bytes

Last-Modifiedis altijd de huidige tijd.

Opmerking: het $date_gmt-formaat van nginx is niet volgens de HTTP-specificatie (zie het formaat wijzigen).


Antwoord 2, autoriteit 21%

De richtlijnen expiresen add_headerhebben geen invloed op de NGINX-caching van de bestanden, die gaan puur over wat de browser ziet.

Wat u in plaats daarvan waarschijnlijk wilt, is:

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

Hoewel meestal .js enz. het ding is dat u in de cache zou plaatsen, dus misschien moet u het cachen gewoon helemaal uitschakelen?


Antwoord 3, autoriteit 14%

Wat u zoekt is een eenvoudige richtlijn zoals:

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

Het bovenstaande zal de extensies binnen de () niet cachen. U kunt verschillende richtlijnen configureren voor verschillende bestandstypen.


Antwoord 4, autoriteit 6%

Onthoud dat je sendfile off;of cache-headers werken niet.
Ik gebruik dit geknipt:

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; 
    }

Antwoord 5, autoriteit 2%

Ik heb de volgende virtuele Nginx-host (statische inhoud) voor lokaal ontwikkelingswerk om alle browsercaching uit te schakelen:

   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;
        }
    }

Antwoord 6

Ik weet dat deze vraag een beetje oud is, maar ik zou willen voorstellen om wat cachebraking-hash te gebruiken in de url van het javascript. Dit werkt perfect in productie en tijdens ontwikkeling, omdat je zowel oneindige cachetijden als instant updates kunt hebben wanneer er wijzigingen optreden.

Laten we aannemen dat je een javascript-bestand /js/script.min.jshebt,
maar in het verwijzende html/php-bestand gebruik je niet het eigenlijke pad, maar:

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

Dus elke keer dat het bestand wordt gewijzigd, krijgt de browser een andere url, wat op zijn beurt betekent dat het niet in de cache kan worden opgeslagen, zowel lokaal als op een tussenliggende proxy.

Om dit te laten werken, moet nginx elk verzoek naar /js/script.[0-9a-f]{32}.min.js herschrijven naar de originele bestandsnaam. In mijn geval gebruik ik de volgende richtlijn (ook voor css):

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;
        }

Ik vermoed dat de filemtime-aanroep niet eens schijftoegang op de server vereist, zoals het zou moeten zijn in de bestandscache van linux. Als je twijfels hebt of statische html-bestanden hebt, kun je ook een vaste willekeurige waarde (of incrementele of content-hash) gebruiken die wordt bijgewerkt wanneer je javascript / css-preprocessor is voltooid of een van je git-hooks dit laten wijzigen.

In theorie zou je ook een cachebreaker als dummy-parameter kunnen gebruiken (zoals /js/script.min.js?cachebreak=0123456789abcfef), maar dan wordt het bestand niet gecached door tenminste sommige proxy’s vanwege de “?“.

Other episodes