解决golang http重定向失效的问题

 更新时间:2020年12月15日 10:55:10   作者:parFu  
这篇文章主要介绍了解决golang http重定向失效的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

最近在学习GoLang,在使用http重定向的时候发现了一个很有趣的现象,在这里记录一下。

r.GET("/index", func(c *gin.Context) {
 c.Redirect(http.StatusMovedPermanently, "http://www.baidu.com/")
})

本来写了这么一段代码,将我的路由重定向到“百度”,第一次试验成功了。之后当我想重新定向到其它网站,或者不重定向而试验其它逻辑的时候,发现在浏览器中,永远只是定向到“百度”。非常疑惑,明明程序都重新运行了呀。后来我发现,用postman或者另一个浏览器打开,我新写的逻辑是能实现的。

最后清空了浏览器近一小时的记录,发现能实现新逻辑了。

所以应该是因为浏览器缓存导致直接在缓存中取内容,而不是从我服务端。

补充:golang不想http自动处理重定向的解决方案

前言

有时候发送http请求不想让库自动帮忙处理重定向,库里面默认的是会把所有重定向都完成一遍,结果就是最后一个没有重定向的请求的结果。

因此需要一种方案直接获取首次访问的结果,不走重定向。

go的http库里面是使用如下代码检查重定向的,以前我傻傻的修改源码让下面这段代码直接返回,这样需要重新编译go自带的库,后来发现更简单的方案。

if err == ErrUseLastResponse {
 return resp, nil // 这里是拦截重定向,如果不拦截则走下面的重定向判断
} 
var shouldRedirect bool
redirectMethod, shouldRedirect, includeBody = redirectBehavior(req.Method, resp, reqs[0])
if !shouldRedirect {
 return resp, nil
}

解决方案

下面代码可以验证自动处理重定向,以及不走重定向的方案。

package main 
import (
 "io/ioutil"
 "log"
 "net/http"
 "time"
) 
func main() {
 go server()
 time.Sleep(time.Second)
 mUrl := "http://127.0.0.1:12345/post"
 { // 常规方法
  req, err := http.NewRequest(http.MethodPost, mUrl, nil)
  if err != nil {
   log.Fatal(err)
  }
  resp, err := http.DefaultClient.Do(req)
  if resp != nil {
   defer resp.Body.Close()
  }
  if err != nil {
   log.Fatal(err)
  }
  byt, err := ioutil.ReadAll(resp.Body)
  if err != nil {
   log.Fatal(err)
  }
  log.Println(resp.StatusCode, "|", string(byt[:128]))
 } 
 { // 去掉自动处理重定向
  req, err := http.NewRequest(http.MethodPost, mUrl, nil)
  if err != nil {
   log.Fatal(err)
  }
  resp, err := http.DefaultTransport.RoundTrip(req)
  if resp != nil {
   defer resp.Body.Close()
  }
  if err != nil {
   log.Fatal(err)
  }
  byt, err := ioutil.ReadAll(resp.Body)
  if err != nil {
   log.Fatal(err)
  }
  log.Println(resp.StatusCode, "|", string(byt[:128]))
 }
 
 { // 另一种不要重定向的方法
  req, err := http.NewRequest(http.MethodPost, mUrl, nil)
  if err != nil {
   log.Fatal(err)
  }
  client := &http.Client{
   CheckRedirect: func(req *http.Request, via []*http.Request) error {
    return http.ErrUseLastResponse /* 不进入重定向 */
   },
  }
  resp, err := client.Do(req)
  if resp != nil {
   defer resp.Body.Close()
  }
  if err != nil {
   log.Fatal(err)
  }
  byt, err := ioutil.ReadAll(resp.Body)
  if err != nil {
   log.Fatal(err)
  }
  log.Println(resp.StatusCode, "|", string(byt[:128]))
 }
} 
// 下面开启一个服务,重定向到百度
func server() {
 http.HandleFunc("/post", mPost)
 http.ListenAndServe(":12345", nil)
} 
func mPost(w http.ResponseWriter, r *http.Request) {
 http.Redirect(w, r, "http://www.baidu.com", http.StatusFound)
 w.Write([]byte(time.Now().String()))
}

结论

如下的第一个请求是直接返回百度的网页,及重定向以后的内容。第二个请求直接返回第一个302重定向的内容。

2020/10/14 13:11:56 200 | 百度一下,你就知道

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

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。如有错误或未考虑完全的地方,望不吝赐教。

相关文章

  • go换国内源的方法步骤

    go换国内源的方法步骤

    在中国境内,由于网络原因,直接下载Go语言的包可能会遇到速度慢或下载失败的问题,可以使用国内的Go模块代理来加速下载速度,本文就来介绍一下go换国内源的方法步骤,感兴趣的可以了解一下
    2024-09-09
  • Gorm存在时更新,不存在时创建的问题

    Gorm存在时更新,不存在时创建的问题

    这篇文章主要介绍了Gorm存在时更新,不存在时创建的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-08-08
  • 详解Go语言中的监视器模式与配置热更新

    详解Go语言中的监视器模式与配置热更新

    这篇文章主要为大家详细介绍了Go语言中的监视器模式与配置热更新的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2024-03-03
  • Go语言基础学习之数组的使用详解

    Go语言基础学习之数组的使用详解

    数组相必大家都很熟悉,各大语言也都有数组的身影。Go 语言也提供了数组类型的数据结构。本文就来通过一些简单的示例带大家了解一下Go语言中数组的使用,希望对大家有所帮助
    2022-12-12
  • 搭建Go语言的ORM框架Gorm的具体步骤(从Java到go)

    搭建Go语言的ORM框架Gorm的具体步骤(从Java到go)

    很多朋友不知道如何使用Goland软件,搭建一个ORM框架GORM,今天小编给大家分享一篇教程关于搭建Go语言的ORM框架Gorm的具体步骤(从Java到go),感兴趣的朋友跟随小编一起学习下吧
    2022-09-09
  • Golang编程并发工具库MapReduce使用实践

    Golang编程并发工具库MapReduce使用实践

    这篇文章主要为大家介绍了Golang并发工具库MapReduce的使用实践,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-04-04
  • go实现for range迭代时修改值的操作

    go实现for range迭代时修改值的操作

    这篇文章主要介绍了go实现for range迭代时修改值的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-04-04
  • Golang极简入门教程(一):基本概念

    Golang极简入门教程(一):基本概念

    这篇文章主要介绍了Golang极简入门教程(一):基本概念,本文讲解了Golang的基本知识、基础语法、相关术语等,需要的朋友可以参考下
    2014-10-10
  • 一文带你深入理解Go语言中的sync.Cond

    一文带你深入理解Go语言中的sync.Cond

    sync.Cond 表示的是条件变量,它是一种同步机制,用来协调多个 goroutine 之间的同步。本文将通过示例为大家介绍Go语言中sync.Cond的使用,需要的可以参考一下
    2023-01-01
  • go语言使用第三方包 json化结构体操作示例

    go语言使用第三方包 json化结构体操作示例

    这篇文章主要介绍了go语言使用第三方包 json化结构体操作,结合实例形式分析了Go语言ffjson包git安装及结构体转json字符串相关操作技巧,需要的朋友可以参考下
    2019-06-06

最新评论