Zac
Zac

Reputation: 831

How can I force the client to re-download my website?

I'm writing a web server in Go, using the github.com/gorilla/mux router. My program checks if the client has a cookie called "name" and based on that, serves one of two files. Here's the handler function:

func indexHandler(w http.ResponseWriter, r *http.Request) {
    if name, err := r.Cookie("name"); err == nil && name.Value != "" {
        http.ServeFile(w, r, "static/messager.html")
    } else {
        http.ServeFile(w, r, "static/index.html")
    }
}

Testing this on Firefox, I load my website, which correctly serves index.html since I don't have the cookie set. In index.html, there's a form which sets the cookie and reloads the page when submitted.

This is the problem. The page reloads, but due to caching index.html is still displayed in the browser (despite the server actually serving messager.html - I added a debug log.) I can reload the page manually as many times as I want, making no difference, but once I do a hard refresh it works and displays messager.html.

This only seems to happen on Firefox (I've tested Safari, Edge, and Firefox). Any suggestions on how I can force the browser to display the correct page?

Upvotes: 0

Views: 415

Answers (1)

Peter
Peter

Reputation: 31691

http.ServeFile sends a Last-Modified header (with the value set to the file's mtime), and no Cache-Control header. In this case browsers will implement heuristics to determine if and how long the response may be cached.

To instruct clients not to cache a response, send the Cache-Control header yourself:

func indexHandler(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Cache-Control", "max-age=0")

    if name, err := r.Cookie("name"); err == nil && name.Value != "" {
        http.ServeFile(w, r, "static/messager.html")
    } else {
        http.ServeFile(w, r, "static/index.html")
    }
}

Caution: the Cache-Control header is really unintuitive. For instance, there is a value called "no-cache", but that doesn't actually cause clients not to cache a response. Read the docs carefully to get your desired affect.

Upvotes: 2

Related Questions