Problem: You want to serve static files such as images, CSS, and JavaScript files.
Solution: Use the http.FileServer function to serve static files.
func main() { dir := http.Dir("./static") fs := http.FileServer(dir) http.Handle("/", fs) http.ListenAndServe(":8000", nil) }
First, you need to understand where you want to serve the files from. For this, use http.Dir . Despite how it looks, http.Dir is not a function but a type. It’s a type that implements the http.FileSystem interface so the first line typecasts the directory such that it becomes a http.Dir .
Next, the http.FileServer function takes in the http.Dir as a parameter and returns an http.Handler that can be used to serve the files.
Finally, call the http.Handle function to register the http.Handler as the handler for the / URL pattern.
The previous information broke down the steps, but most of the time, you’ll use it this way:
func main() { http.Handle("/", http.FileServer(http.Dir("./static"))) http.ListenAndServe(":8000", nil) }
This works because you use / as the URL to start from. However, once you start using different ones, you’ll need to use http.StripPrefix to remove the prefix:
func main() { dir := http.Dir("./static") fs := http.FileServer(dir) fs = http.StripPrefix("/static", fs) http.Handle("/static/", fs) http.ListenAndServe(":8000", nil) }
The main difference comes when you want to use /static as the root URL (or any other starting point). If you proceed as before, when the user requests for a file /static/rfc2616.txt , the file server you look for a file called /static/static/rfc2616.txt . To avoid this, use the http.StripPrefix function to remove the prefix /static from the request URL before it is passed to the file server. As before, you normally do it all in a single line:
func main() { http.Handle("/static/", http.StripPrefix("/static", http.FileServer(http.Dir("./static")))) http.ListenAndServe(":8000", nil) }
This seems quite redundant, but actually there is another reason for this. In the example, you have a directory called static , and you want to serve it out from the /static URL. You could have a directory called datafiles , for example, but you want the user to access it from the /static URL:
func main() { http.Handle("/static/", http.StripPrefix("/static", http.FileServer(http.Dir("./datafiles")))) http.ListenAndServe(":8000", nil) }
You should be aware that http.FileServer will list all the contents of the directory that it is serving. This might not be a major problem if you don’t care if the user can see the contents of the directory.
However, if you want to prevent this, you can create and place an index.html file in the directory. This file will be served instead of the directory listing. index.html can be anything, including being empty; it just needs to be there.
If you want to serve a single file, just use http.ServeFile :
func main() { file := func(w http.ResponseWriter, r *http.Request) { http.ServeFile(w, r, "./static/a.txt") } http.HandleFunc("/static/a", file) http.ListenAndServe(":8000", nil) }
The http.ServeFile function takes in an http.ResponseWriter , an http.Request , and the path to the file you want to serve. If you wrap it around an anonymous function, you can use it as a handler function, which we did in the example.