Paul Parker Paul Parker - 28 days ago 11
HTTP Question

Can Go easily emulate the behaviour of Laravel's return Redirect::back()?

While using Laravel, I really appreciated being able to use:

return Redirect::back();


to return to the previous URL after a
POST
request.

Is there a simple in-built way to do this in Go?

http.Redirect(w, r, backURL, http.StatusSeeOther)


where
backURL
is the URL that the POST request was made from.

I've looked through
net/http
and searched SE and google, but I haven't turned anything up. Failing an easy way, I'd appreciate any pointer toward the idiomatic way of doing this in Go.

Answer

The Redirect::back() function uses the URL from the Referer HTTP header specified by the client (browser).

You could access this header value like r.Header.Get("Referer"), but the http.Request type also provides a direct Request.Referer() method that returns the value of this Referer field, which also deals with its 2 possible forms ("Referer" and "Referrer").

This is how you can mimic the "go back" behavior:

func PostHandler(w http.ResponseWriter, r *http.Request) {
    // Process form, then:
    if rf := r.Referer(); rf != "" {
        http.Redirect(w, r, rf, http.StatusSeeOther)
        return
    }

    // No Referer specified, supply your own response
    // or redirect to a default / home page
    http.Redirect(w, r, "/", http.StatusSeeOther)
}

If you want to call this from many handlers, you may capture this functionality in a helper function:

func redirectBack(w http.ResponseWriter, r *http.Request) {
    if rf := r.Referer(); rf != "" {
        http.Redirect(w, r, rf, http.StatusSeeOther)
        return
    }

    // No Referer specified, supply your own response
    // or redirect to a default / home page
    http.Redirect(w, r, "/", http.StatusSeeOther)
}

And then using it:

func PostHandler(w http.ResponseWriter, r *http.Request) {
    // Process form, then:
    redirectBack(w, r)
}