详解golang开发中http请求redirect的问题

 更新时间:2020年10月27日 12:52  点击:1587

这两天在开发项目的时候遇到了一个问题,请求了一个URL,它会302到另一个地址,本意上只是想检查这个URL是否会做3XX的redirect跳转,结果每次reqeust都会返回最后一跳的结果。后来就看了下源码,了解下请求跳转的机制

实现代码

看下实现的简单代码

func main() {
 client := &http.Client{}
 url := "http://www.qq.com"
 reqest, err := http.NewRequest("GET", url, nil)
 if err != nil {
 panic(err)
 }
 response, _ := client.Do(reqest)
 fmt.Println(response.Status)
}

curl http://www.qq.com
<html>
<head><title>302 Found</title></head>
<body bgcolor="white">
<center><h1>302 Found</h1></center>
<hr><center>stgw/1.3.12.4_1.13.5</center>
</body>
</html>

我们知道在浏览器里面输入http://www.qq.com会302跳转到https://www.qq.com。我们使用curl可以看到使用302的跳转。

可是我只想获取第一跳的的response 的状态码。发现没法实现了,所以看了下源码。

http请求为什么可以做到多次redirect

看了下 client.Do 源码实现

607 err = c.checkRedirect(req, reqs)

代码的上下文,可以看出 req是将要请求的request,reqs已经请求过的request

主要看下checkRedirect

func (c *Client) checkRedirect(req *Request, via []*Request) error {
 fn := c.CheckRedirect
 if fn == nil {
 fn = defaultCheckRedirect
 }
 return fn(req, via)
}

可以看到如果设置了checkRedirect就执行checkRedirect,如果没有设置就执行 defaultCheckRedirect。

再看下 defaultCheckRedirect

func defaultCheckRedirect(req *Request, via []*Request) error {
 if len(via) >= 10 {
 return errors.New("stopped after 10 redirects")
 }
 return nil
}

可以看到最多可以redirect 10次,如果大于10的跳转就抛出错误结束这次请求了。

大体上流程已经搞明白。只要设置checkRedirect返回error,理论上就能实现只请求一次的目的。

func main() {
 client := &http.Client{}
 url := "http://www.qq.com"
 reqest, err := http.NewRequest("GET", url, nil)
 if err != nil {
 panic(err)
 }
 client.CheckRedirect = func(req *http.Request, via []*http.Request) error {
 return fmt.Errorf("first response")
 }
 response, _ := client.Do(reqest)
 fmt.Println(response.StatusCode)
}

/private/var/folders/4h/lrsc4fyd12v9ctl31ggk5ckc0000gp/T/___go_build_main_go #gosetup
302

基本实现了。

其实,在CheckRedirect方法上面有一行说明,

ErrUseLastResponse can be returned by Client.CheckRedirect hooks to control how redirects are processed. If returned, the next request is not sent and the most recent response is returned with its body unclosed.

Client.CheckRedirect挂钩可以返回ErrUseLastResponse,以控制如何处理重定向。 如果返回,则不发送下一个请求,并且返回最近的响应且其主体未关闭。

可以看到返回 ErrUseLastResponse是官方的建议的设置

最终的代码实现应该是这样的。

func main() {
 client := &http.Client{}
 url := "http://www.qq.com"
 reqest, err := http.NewRequest("GET", url, nil)
 if err != nil {
 panic(err)
 }
 client.CheckRedirect = func(req *http.Request, via []*http.Request) error {
 return http.ErrUseLastResponse
 }
 response, _ := client.Do(reqest)
 fmt.Println(response.StatusCode)
}

到此这篇关于详解golang开发中http请求redirect的问题的文章就介绍到这了,更多相关golang http请求redirect内容请搜索猪先飞以前的文章或继续浏览下面的相关文章希望大家以后多多支持猪先飞! 

[!--infotagslink--]

相关文章

  • C#实现简单的Http请求实例

    这篇文章主要介绍了C#实现简单的Http请求的方法,以实例形式较为详细的分析了C#实现Http请求的具体方法,需要的朋友可以参考下...2020-06-25
  • Java如何发起http请求的实现(GET/POST)

    这篇文章主要介绍了Java如何发起http请求的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-03-31
  • C#实现HTTP下载文件的方法

    这篇文章主要介绍了C#实现HTTP下载文件的方法,包括了HTTP通信的创建、本地文件的写入等,非常具有实用价值,需要的朋友可以参考下...2020-06-25
  • C#使用Http Post方式传递Json数据字符串调用Web Service

    这篇文章主要为大家详细介绍了C#使用Http Post方式传递Json数据字符串调用Web Service,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-06-25
  • 解决Feign切换client到okhttp无法生效的坑(出现原因说明)

    这篇文章主要介绍了解决Feign切换client到okhttp无法生效的坑(出现原因说明),具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-02-25
  • 完美解决SpringCloud-OpenFeign使用okhttp替换不生效问题

    这篇文章主要介绍了完美解决SpringCloud-OpenFeign使用okhttp替换不生效问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-02-25
  • 解决Java处理HTTP请求超时的问题

    这篇文章主要介绍了解决Java处理HTTP请求超时的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-29
  • C#模拟http 发送post或get请求的简单实例

    下面小编就为大家带来一篇C#模拟http 发送post或get请求的简单实例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2020-06-25
  • golang 调用 php7详解及实例

    这篇文章主要介绍了golang 调用 php7详解及实例的相关资料,需要的朋友可以参考下...2017-01-15
  • Spring Boot项目@RestController使用重定向redirect方式

    这篇文章主要介绍了Spring Boot项目@RestController使用重定向redirect方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-09-02
  • HTTP 415错误-Unsupported media type详解

    这篇文章主要介绍了HTTP 415错误-Unsupported media type详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下...2021-08-16
  • Angular利用HTTP POST下载流文件的步骤记录

    这篇文章主要给大家介绍了关于Angular利用HTTP POST下载流文件的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者使用Angular具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧...2020-07-26
  • 详解nginx同一端口监听多个域名和同时监听http与https

    这篇文章主要介绍了详解nginx同一端口监听多个域名和同时监听http与https的相关资料,需要的朋友可以参考下...2017-07-06
  • 微信小程序封装http访问网络库实例代码

    这篇文章主要介绍了微信小程序封装http访问网络库实例代码的相关资料,需要的朋友可以参考下...2017-05-27
  • Node.js之http模块的用法

    这篇文章主要介绍了Node.js之http模块的用法,对Node.js感兴趣的同学,可以参考下...2021-04-25
  • 用golang如何替换某个文件中的字符串

    这篇文章主要介绍了用golang实现替换某个文件中的字符串操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-04-25
  • Golang中的自定义类型之间的转换的实现(type conversion)

    这篇文章主要介绍了Golang中的自定义类型之间的转换的实现(type conversion),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-21
  • spring cloud gateway中如何读取请求参数

    这篇文章主要介绍了spring cloud gateway中如何读取请求参数的操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-07-15
  • 快速学习AngularJs HTTP响应拦截器

    任何时候,如果我们想要为请求添加全局功能,例如身份认证、错误处理等,在请求发送给服务器之前或服务器返回时对其进行拦截,是比较好的实现手段...2016-01-05
  • golang在GRPC中设置client的超时时间

    这篇文章主要介绍了golang在GRPC中设置client的超时时间,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-04-27