user1710722
user1710722

Reputation: 55

How to force nginx to reload client's browser for content change?

I have a very simple setup, but I am unable to achieve the end goal as of yet. I have an nginx installed on a VM that is serving a static html page. This html page contains the code for a video that I want to loop. I want to be able to replace the video file in the video directory and have nginx force the client's browser which is displaying the old video to reload and start playing the new file without restarting nginx or refreshing the browser manually. I should mention that the client browser is on a TV that displays the video and I do not want to manually refresh the browser on the TV and have this done automatically.

I have found few meta tags by searching around to have it work but it does not work for me. The page serves the old video and does not refresh after an hour (the value that I have specified in the meta tag).

<!DOCTYPE html>
<html>
<head>
<title>my video</title>
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Expires" content="-1">
<meta http-equiv="CACHE-CONTROL" content="NO-CACHE">
<meta http-equiv="refresh" content="3600">
<style>
    body {
        position: absolute;
            overflow: hidden;
            width: 100%;
            height: 100%;
    }

    #myvideo {
        width: 100%;
        height: 100%;
    }
</style>
</head>
<body>
    <!-- The video -->
    <video autoplay muted loop id="myvideo">
        <source src="videos/main.mp4" type="video/mp4">
    </video>
</body>
</html>

I upload a different video to video directory with the same name "main.mp4" and want the nginx to force the browser to reload and display the updated video.

Upvotes: 2

Views: 10674

Answers (3)

SyedAsadRazaDevops
SyedAsadRazaDevops

Reputation: 387

To configure Nginx to not reload a website from the cache when a client user hits the website, you can use the proxy_cache_bypass directive.

server {
    root /var/www/public_html/react/build;
    index index.html index.htm index.nginx-debian.html;
    server_name myapp.com www.myapp.com;

 location / {
        try_files $uri  /index.html;

    proxy_cache my_cache;
    proxy_cache_bypass $http_pragma;
    proxy_cache_revalidate on;
    proxy_cache_min_uses 3;
    proxy_cache_valid 200 60m;
    proxy_cache_valid 404 1m;
    proxy_cache_valid any 0;

    add_header Cache-Control "no-store, no-cache, must-revalidate";
    add_header Cache-Control "max-age=31536000, public";
    }

Upvotes: 0

simon
simon

Reputation: 1191

Another option is using Refresh HTTP header:

    location = /chart.auto.png {    
        alias /run/data/chart.png;
        add_header Refresh "5; url=https://example.com/chart.auto.png";
    }

This headers makes the browser either to refresh this very URL or possibly go to another URL after 5 seconds.

This works for any type of content (not only HTML pages), as seen in the example.


While this may work fine, it is still recommended to disable caching for the object you provide:

    add_header Last-Modified $date_gmt;
    add_header Cache-Control 'no-store, no-cache';
    if_modified_since off;
    expires off;
    etag off;

Upvotes: 0

Danila Vershinin
Danila Vershinin

Reputation: 9845

Few things to check/keep in mind:

While <meta http-equiv="refresh" content="3600"> should work just fine, some (very rare ones) browsers may not support it. In that case, you might try adding Javascript-based solution, e.g.:

<script>
setTimeout(function() { window.location.reload(true); }, 60*60*1000);
</script>

The true will ensure that while reloading the page, the browser will skip its cache and load the page from the server.

Since your page uses/links to the same video filename internally, you have to ensure that http://example.com/videos/main.mp4 does not have positive caching headers.

You can use curl to check headers like so:

curl -IL http://example.com/videos/main.mp4

See what is the value for Cache-Control and Expires. You can have both, or either of those headers. For your case, they should dictate cacheability of less than one hour or none at all.

In NGINX you can set this with:

location = /videos/main.mp4 {
    expires -1;
}

Which basically tells it to send expiration in the past of 1 second behind the time when the video file was fetched (= no cache).

Upvotes: 1

Related Questions