zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    1012 The Best Rank (25 分)(排序)
    1011. World Cup Betting (20)(查找元素)
    1009 Product of Polynomials (25 分)(模拟)
    1008 Elevator (20 分)(数学问题)
    1006 Sign In and Sign Out (25 分)(查找元素)
    1005 Spell It Right (20 分)(字符串处理)
    Kafka Connect 出现ERROR Failed to flush WorkerSourceTask{id=local-file-source-0}, timed out while wait
    flume、kafka、avro组成的消息系统
    Java23种设计模式总结【转载】
    Java编程 思维导图
  • 原文地址:https://www.cnblogs.com/janbar/p/13814251.html
Copyright © 2011-2022 走看看