In a Go application, you're leveraging a single-page web application and serving its assets using a static file server. While the server functions well for serving existing assets in the root directory, it throws a 404 Not Found error if a requested file is not present.
Your objective is to modify the server's behavior to serve index.html for any unrecognized URL. This is crucial as your single-page application handles rendering based on the served HTML and JavaScript.
The default handler provided by http.FileServer() lacks customization options, including handling 404 not found responses. To address this limitation, we'll wrap the handler and implement our logic within the wrapper.
We'll create a custom http.ResponseWriter that wraps the original response writer. This custom response writer will:
Below is an example of such a custom response writer:
<code class="go">type NotFoundRedirectRespWr struct { http.ResponseWriter // Embed the base HTTP response writer status int } func (w *NotFoundRedirectRespWr) WriteHeader(status int) { w.status = status // Store the status code if status != http.StatusNotFound { w.ResponseWriter.WriteHeader(status) // Proceed normally for non-404 statuses } } func (w *NotFoundRedirectRespWr) Write(p []byte) (int, error) { if w.status != http.StatusNotFound { return w.ResponseWriter.Write(p) // Proceed normally for non-404 statuses } return len(p), nil // Pretend that the data was successfully written, but discard it }</code>
Next, we wrap the handler returned by http.FileServer(). The wrapper handler will:
Here's an example of the wrapper handler:
<code class="go">func wrapHandler(h http.Handler) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { nfrw := &NotFoundRedirectRespWr{ResponseWriter: w} h.ServeHTTP(nfrw, r) // Call the default handler with our custom response writer if nfrw.status == 404 { log.Printf("Redirecting %s to index.html.", r.RequestURI) http.Redirect(w, r, "/index.html", http.StatusFound) } } }</code>
Now, in your main() function, utilize the wrapper handler to modify the behavior of the static file server.
<code class="go">func main() { fs := wrapHandler(http.FileServer(http.Dir("."))) // Wrap the handler http.HandleFunc("/", fs) panic(http.ListenAndServe(":8080", nil)) // Start serving files with the custom handler }</code>
With this approach, all requests to URLs that correspond to non-existent files will trigger a redirect to index.html. Your single-page application will function as intended, rendering the appropriate content based on the served HTML and JavaScript.
The above is the detailed content of How to Handle File Not Found Exceptions in a Go Static File Server for Single-Page Applications?. For more information, please follow other related articles on the PHP Chinese website!