如何使用两个client.Do使用golang

时间:2018-04-24 14:54:54

标签: go cookies client

我使用包去net / http,我想发布到登录网址,然后获取节点页面 我想使用两次client.Do因为cookie 这是我的代码

package main

import (
    "log"
    "net/http"
    "net/http/cookiejar"
    "net/url"
)

func main() {
    cookieJar, _ := cookiejar.New(nil)
    client := &http.Client{
        Jar: cookieJar,
    }

    loginUrl, _ := url.Parse("https://pro.v2bz.com/auth/login")

    v := url.Values{}
    v.Add("email", "1231231231@qq.com")
    v.Add("passwd", "1231231231")

    req := &http.Request{
        Method:   "POST",
        URL:      loginUrl,
        PostForm: v,
    }
    resp, err := client.Do(req)
    if err != nil {
        log.Println("login failed", err)
    }
    defer resp.Body.Close()
    log.Println(resp.Status)

    nodeUrl, _ := url.Parse("https://pro.v2bz.com/user/node")
    nodeReq := &http.Request{
        Method: "GET",
        URL:    nodeUrl,
    }

    nodeResp, err := client.Do(nodeReq)
    if err != nil {
        log.Println("node request failed", err)
    }
    log.Println(nodeResp.Status)
}

但是我得到了这个错误 恐慌:分配到nil地图中的条目 我怎么能在一个代码中使用两次client.Do?

3 个答案:

答案 0 :(得分:2)

错误不是因为您使用client.Do两次。事实上你可以多次打电话。错误消息表示在某处访问了未分配的变量(map)。在您的情况下,导致错误的变量是Request.Header。使用适当的方法构建请求,例如http.NewRequest

nodeReq, err := http.NewRequest("GET", nodeUrl, nil)

在发送表单内容的POST请求时,请使用Client.PostForm,例如

resp, err := client.PostForm(loginUrl, v)

此方法将设置相应的Content-Type标头,然后调用client.Do

答案 1 :(得分:2)

request.go发生错误(第389行):

// AddCookie adds a cookie to the request. Per RFC 6265 section 5.4,
// AddCookie does not attach more than one Cookie header field. That
// means all cookies, if any, are written into the same line,
// separated by semicolon.
func (r *Request) AddCookie(c *Cookie) {
    ...
    if c := r.Header.Get("Cookie"); c != "" {
        r.Header.Set("Cookie", c+"; "+s)
    } else {
        r.Header.Set("Cookie", s)
    }
}

请参阅该请求尝试设置标头。如果你要制作Header,那就行了。

nodeReq := &http.Request{
    Method: "GET",
    URL:    nodeUrl,
    TLS:    resp.TLS,
    Header: make(Header),
}

适当的方法是http.NewRequest。 链接:https://golang.org/pkg/net/http/#NewRequest

在http.NewRequest(request.go第778行)中,标题创建如下:

req := &Request{
    Method:     method,
    URL:        u,
    Proto:      "HTTP/1.1",
    ProtoMajor: 1,
    ProtoMinor: 1,
    Header:     make(Header),
    Body:       rc,
    Host:       u.Host,
}

另请参阅如果您使用HTTP,非HTTPS,则不需要Header,也可以使用!!

答案 2 :(得分:0)

恐慌因为 Request.Header 没有初始化,在第二个 Client.Do ,Cookie无法添加到 Request.Header (NodeReq)。 In this link i learn how to add header by my self 一个解决方案是

v := url.Values{}
v.Add("email", "1231231231@qq.com")
v.Add("passwd", "1231231231")

req, err := http.NewRequest("POST", "https://pro.v2bz.com/auth/login", strings.NewReader(v.Encode()))
req.PostForm = v
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")

在第二个请求,因为@ aristofanio-garcia说使用

nodeReq := &http.Request{
    Method: "GET",
    URL:    nodeUrl,
    Header: make(http.Header), //add this to initialize Request.Header so the cookies could add into header
}