禁用JavaScript文件的nginx缓存

u59ebvdq  于 2023-02-11  发布在  Java
关注(0)|答案(6)|浏览(182)

好吧,我几乎要放弃这个了,但是我怎么才能禁用Nginx对JavaScript文件的缓存呢?我使用的是一个带有Nginx的Docker容器。当我现在在JavaScript文件中更改一些内容时,我需要多次重新加载,直到新文件出现。
我怎么知道它是Nginx而不是浏览器/Docker?
浏览器:我在命令行上使用curl来模拟请求,也遇到了同样的问题。另外,我使用的是CacheKiller插件,并在Chrome开发工具中禁用了缓存。
Docker:当我连接到容器的bash,并在更改文件后使用cat时,我立即得到了正确的结果。
我将我的nginx.confsites-enabled更改为这个(我在另一个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;
}

但是,在重新构建容器(并确保它位于cat的容器中)之后,它仍然不起作用。

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

hmtdttj41#

我有以下nginx虚拟主机(静态内容)用于本地开发工作,以禁用所有浏览器缓存:

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

未发送缓存标头:

$ 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-Modified始终为当前时间。

注意:nginx的$date_gmt不符合HTTP规范(see changing the format)。

要禁用特定文件扩展名的缓存(例如OP请求的JS):

location ~* \.js$ {
    expires -1;
}

请参阅下面Nitai的回答,以扩展文件扩展名列表-使用非捕获组正则表达式模式。

wko9yo5t

wko9yo5t2#

expiresadd_header指令对NGINX缓存文件没有任何影响,它们纯粹是关于浏览器看到的内容。
您可能需要的是:

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

虽然通常.js等是你会缓存的东西,所以也许你应该完全禁用缓存?

omqzjyyz

omqzjyyz3#

您需要的是一个简单的指令,例如:

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

以上操作不会缓存()中的扩展名。您可以为不同的文件类型配置不同的指令。

7gs2gvoe

7gs2gvoe4#

记住设置sendfile off;或缓存头不起作用。我使用这个代码片段:

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

k0pti3hp5#

我有以下Nginx虚拟主机(静态内容)用于本地开发工作,以禁用所有浏览器缓存:

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

fjnneemd6#

我知道这个问题有点老了,但是我建议在javascript的url中使用一些cachebraking散列,这在生产和开发过程中都能完美地工作,因为你可以同时拥有无限的缓存时间和即时更新。
假设您有一个javascript文件**/js/script.min.js**,但在引用的html/php文件中,您没有使用实际路径,而是:

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

所以每次文件被修改,浏览器都会得到一个不同的url,这意味着它不能被缓存,无论是本地的还是中间的代理。
为了实现这个功能,你需要nginx把任何对/js/script.[0-9a-f]{32}.min.js的请求重写成原来的文件名。在我的例子中,我使用了下面的指令(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;
        }

我猜filemtime调用甚至不需要访问服务器上的磁盘,因为它应该在linux的文件缓存中,如果你有疑问或静态html文件,你也可以使用一个固定的随机值(或增量或内容哈希),当你的javascript / css预处理器完成时,它会被更新,或让你的git钩子之一改变它。
理论上,您也可以使用一个cachebreaker作为伪参数(如/js/script.min.js?cachebreak= 0123456789 abcfef),但由于“",文件至少不会被某些代理缓存。

相关问题