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

 更新时间:2020年10月27日 09:55:29   作者:飞翔码农  
这篇文章主要介绍了详解golang开发中http请求redirect的问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

这两天在开发项目的时候遇到了一个问题,请求了一个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内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家! 

相关文章

  • 详解Golang时间处理的踩坑及解决

    详解Golang时间处理的踩坑及解决

    在各个语言之中都有时间类型的处理,这篇文章主要和大家分享一下Golang进行时间处理时哪里最容易踩坑以及解决方法,需要的可以参考一下
    2023-01-01
  • 手把手带你走进Go语言之条件表达式

    手把手带你走进Go语言之条件表达式

    条件表达式由条件运算符构成,并常用条件表达式构成一个赋值语句,本文给大家介绍了在Go语言中条件表达式的具体用法,讲述的非常详细,对大家的学习或工作具有一定的参考借鉴价值
    2021-09-09
  • golang实现http服务器处理静态文件示例

    golang实现http服务器处理静态文件示例

    这篇文章主要介绍了golang实现http服务器处理静态文件的方法,涉及Go语言基于http协议处理文件的相关技巧,需要的朋友可以参考下
    2016-07-07
  • 详解Golang的GC三色标记法

    详解Golang的GC三色标记法

    这篇文章主要为大家介绍了Golang的GC三色标记法,文中有详细的实现过程供大家参考,对大家的学习或工作有一定帮助,感兴趣的可以跟着小编一来看看
    2023-05-05
  • 使用Go实现健壮的内存型缓存的方法

    使用Go实现健壮的内存型缓存的方法

    这篇文章主要介绍了使用Go实现健壮的内存型缓存,本文比较了字节缓存和结构体缓存的优劣势,介绍了缓存穿透、缓存错误、缓存预热、缓存传输、故障转移、缓存淘汰等问题,并对一些常见的缓存库进行了基准测试,需要的朋友可以参考下
    2022-05-05
  • Golang操作DuckDB实战案例分享

    Golang操作DuckDB实战案例分享

    DuckDB是一个嵌入式SQL数据库引擎,它与众所周知的SQLite非常相似,但它是为olap风格的工作负载设计的,DuckDB支持各种数据类型和SQL特性,凭借其在以内存为中心的环境中处理高速分析的能力,它迅速受到数据科学家和分析师的欢迎,在这篇博文中,我们将探索在Go中使用DuckDB
    2025-01-01
  • Go编程中常见错误和不良实践解析

    Go编程中常见错误和不良实践解析

    这篇文章主要为大家介绍了Go编程中常见错误和不良实践解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2024-01-01
  • go的strings用法小结

    go的strings用法小结

    strings 是 Go 语言标准库中提供的一个包,用于处理字符串相关的操作,本文主要介绍了go的strings用法小结,具有一定的参考价值,感兴趣的可以了解一下
    2023-08-08
  • Go操作etcd的实现示例

    Go操作etcd的实现示例

    etcd是近几年比较火热的一个开源的、分布式的键值对数据存储系统,提供共享配置、服务的注册和发现,本文主要介绍etcd的安装和使用,感兴趣的可以了解一下
    2021-09-09
  • 浅析Golang中的协程(goroutine)

    浅析Golang中的协程(goroutine)

    在Go语言中,协程(goroutine)是轻量级的线程,它是Go语言中实现并发编程的基础,Go语言中的协程是由Go运行时调度器(scheduler)进行管理和调度的,本文将给大家简单的介绍一下Golang中的协程,需要的朋友可以参考下
    2023-05-05

最新评论