SoFunction
Updated on 2025-03-05

Solve the problem of golang http redirect failure

Recently, I was learning GoLang and found a very interesting phenomenon when using http redirection. Let me record it here.

("/index", func(c *) {
 (, "/")
})

I originally wrote such a piece of code to redirect my route to "Baidu", and the first experiment was successful. Later, when I wanted to redirect to other websites, or experiment with other logic without redirecting, I found that in the browser, I always just targeted to "Baidu". Very confused, the program has obviously been re-run. Later I found that when I opened it with postman or another browser, my newly written logic could be realized.

Finally, I cleared the browser's records for nearly an hour and found that new logic could be realized.

So it should be because the browser cache causes the content to be fetched directly in the cache, rather than from my server side.

Added: Golang does not want http to automatically handle redirects

Preface

Sometimes when sending http requests, you don’t want the library to automatically help with redirects. The default in the library is to complete all redirects, and the result is the result of the last request without redirects.

Therefore, a solution is needed to directly obtain the results of the first visit without redirecting.

Go's http library uses the following code to check redirects. In the past, I foolishly modified the source code and let the following code return directly. This requires recompiling the library that comes with go. Later, I found a simpler solution.

if err == ErrUseLastResponse {
 return resp, nil // Here is the intercept redirection. If you do not intercept, go to the following redirection judgment} 
var shouldRedirect bool
redirectMethod, shouldRedirect, includeBody = redirectBehavior(, resp, reqs[0])
if !shouldRedirect {
 return resp, nil
}

Solution

The following code can verify the automatic redirection processing and the solution to not redirect.

package main 
import (
 "io/ioutil"
 "log"
 "net/http"
 "time"
) 
func main() {
 go server()
 ()
 mUrl := "http://127.0.0.1:12345/post"
 { // General methods  req, err := (, mUrl, nil)
  if err != nil {
   (err)
  }
  resp, err := (req)
  if resp != nil {
   defer ()
  }
  if err != nil {
   (err)
  }
  byt, err := ()
  if err != nil {
   (err)
  }
  (, "|", string(byt[:128]))
 } 
 { // Remove automatic processing of redirects  req, err := (, mUrl, nil)
  if err != nil {
   (err)
  }
  resp, err := (req)
  if resp != nil {
   defer ()
  }
  if err != nil {
   (err)
  }
  byt, err := ()
  if err != nil {
   (err)
  }
  (, "|", string(byt[:128]))
 }
 
 { // Another way to not redirect  req, err := (, mUrl, nil)
  if err != nil {
   (err)
  }
  client := &{
   CheckRedirect: func(req *, via []*) error {
    return  /* Don't enter redirection */
   },
  }
  resp, err := (req)
  if resp != nil {
   defer ()
  }
  if err != nil {
   (err)
  }
  byt, err := ()
  if err != nil {
   (err)
  }
  (, "|", string(byt[:128]))
 }
} 
// Turn on a service below and redirect to Baidufunc server() {
 ("/post", mPost)
 (":12345", nil)
} 
func mPost(w , r *) {
 (w, r, "", )
 ([]byte(().String()))
}

in conclusion

The first request below is to directly return to Baidu's web page and redirect the content afterwards. The second request directly returns the content of the first 302 redirect.

2020/10/14 13:11:56 200 | You will know by Baidu

2020/10/14 13:11:56 302 | 2020-10-14 13:11:56.6559382 +0800 CST m=+1.429170501

2020/10/14 13:11:56 302 | 2020-10-14 13:11:56.6559382 +0800 CST m=+1.429170501

The above is personal experience. I hope you can give you a reference and I hope you can support me more. If there are any mistakes or no complete considerations, I would like to give you advice.