基本使用

最基本的HTTP客户端使用是通过HTTP Method同名的几个操作方法来发送请求,但需要注意的是返回的结果对象需要执行Close防止内存溢出。我们来看几个HTTP客户端请求的简单示例。

发送GET请求,打印出返回值

if r, err := g.Client().Get(ctx, "https://goframe.org"); err != nil {
    panic(err)
}
defer r.Close()
fmt.Println(r.ReadAllString())

发送GET请求,下载远程文件

if r, err := g.Client().Get(ctx, "https://goframe.org/cover.png"); err != nil {
    panic(err)
}
defer r.Close()
gfile.PutBytes("/Users/john/Temp/cover.png", r.ReadAll())

下载文件操作,小文件下载非常简单。需要注意的是,如果远程文件比较大时,服务端会分批返回数据,因此会需要客户端发多个GET请求,每一次通过Header来请求分批的文件范围长度,感兴趣的同学可自行研究相关细节。

发送POST请求,打印出返回值

if r, err := g.Client().Post(ctx, "http://127.0.0.1:8199/form", "name=john&age=18"); err != nil {
    panic(err)
}
defer r.Close()
fmt.Println(r.ReadAllString())

传递多参数的时候用户可以使用&符号进行连接,注意参数值往往需要通过gurl.Encode编码一下。

发送POST请求,参数为map类型,打印出返回值

if r, err := g.Client().Post(
    ctx, 
    "http://127.0.0.1:8199/form",
    g.Map{
        "submit"   : "1",
        "callback" : "http://127.0.0.1/callback?url=http://baidu.com",
    }
)); err != nil {
    panic(err)
}
defer r.Close()
fmt.Println(r.ReadAllString())

传递多参数的时候用户可以使用&符号进行连接,也可以直接使用map其实之前也提到,任意数据类型都支持,包括struct)。

发送POST请求,参数为JSON数据,打印出返回值

if r, err := g.Client().Post(
    ctx,
    "http://user.svc/v1/user/create",
    `{"passport":"john","password":"123456","password-confirm":"123456"}`,
); err != nil {
    panic(err)
}
defer r.Close()
fmt.Println(r.ReadAllString())

可以看到,通过ghttp客户端发送JSON数据请求非常方便,直接通过Post方法提交即可。当没有显式设置ContentType时,客户端会自动识别参数类型并将请求的Content-Type设置为application/json

发送DELETE请求,打印出返回值

if r, err := g.Client().Delete(ctx, "http://user.svc/v1/user/delete/1", "10000"); err != nil {
    panic(err)
}
defer r.Close()
fmt.Println(r.ReadAllString())

*Bytes*Content方法

BytesContent后缀结尾的请求方法为直接获取返回内容的快捷方法,这些方法将会自动读取服务端返回内容并自动关闭请求连接*Bytes方法用于获取[]byte类型结果,*Content方法用于获取string类型结果。需要注意的是,如果请求执行失败,返回内容将会为空。

发送GET请求,打印出返回值

 // 返回content为[]bytes类型
 content := g.Client().GetBytes(ctx, "https://goframe.org")
 // 返回content为string类型
 content := g.Client().GetContent(ctx, "https://goframe.org")

发送POST请求,打印出返回值

// 返回content为[]bytes类型
content := g.Client().PostBytes(
    ctx,
    "http://user.svc/v1/user/create", 
    `{"passport":"john","password":"123456","password-confirm":"123456"}`,
)
// 返回content为string类型
content := g.Client().PostContent(
    ctx,
    "http://user.svc/v1/user/create", 
    `{"passport":"john","password":"123456","password-confirm":"123456"}`,
)

*Var方法

Var后缀结尾的请求方法直接请求并获取HTTP接口结果为g.Var泛型类型便于下一步执行类型转换,特别是将请求结果转换到结构体对象上。往往用于服务端返回格式为JSON/XML的情况,通过返回的g.Var泛型对象可根据需要自动解析。此外,如果请求失败或者请求结果为空,会返回一个空的g.Var泛型对象,不影响转换方法调用。

使用示例:

type User struct {
    Id   int
    Name string
}
// Struct
var user *User
g.Client().GetVar(ctx, url).Scan(&user)
// Struct数组
var users []*User
g.Client().GetVar(ctx, url).Scan(&users)
Content Menu

  • No labels

12 Comments

  1. 示例中使用g.Map 作为post参数,服务端接受到的为 "Content-Type":["application/x-www-form-urlencoded"]

    这里要如何将其设置为json类型呢?


    发现设置header并未生效

    client.Header(map[string]string{
    "Content-Type":"application/json",
    })


    if r, err := g.Client().Post(
        "http://127.0.0.1:8199/form",
        g.Map{
            "submit"   : "1",
            "callback" : "http://127.0.0.1/callback?url=http://baidu.com",
        }
    )); err != nil {
        panic(err)
    } else {
        defer r.Close()
        fmt.Println(r.ReadAllString())
    }
    
    




      1. 你好

        我用g.Client()提交和postman的go示例提交得到结果不一样。

        g.Client().SetHeader("Cookie", "BAIDUID=732CF63499459EE68DE5F3F91FF20D31:FG=1;BAIDUID_BFESS=732CF63499459EE68DE5F3F91FF20D31:FG=1").PostContent(ctx, url, "")

        这个获取不到信息。


        下面的http.Client可以正确获取。

        client := &http.Client{}
        req, _:= http.NewRequest("POST", url, nil)
        req.Header.Add("Cookie", "BAIDUID=732CF63499459EE68DE5F3F91FF20D31:FG=1;BAIDUID_BFESS=732CF63499459EE68DE5F3F91FF20D31:FG=1")
        res, _:= client.Do(req)

  2. 原来要链式操作

    client:=ghttp.Client{}
    response, _ := client.Header(map[string]string{
    "Content-Type":"application/json",
    }).Post(url, data)


  3. 使用g.Client() post提交并设置了cookie,,postman模拟post提交也设置了cookie头参数,两种方式调用返回结果不一致。。。不知道是不是我操作有什么问题。。。。

    1. 那么你是不是应该写出你是怎么操作的?

      ghttp.Client是怎么使用的?
      postman是怎么使用的?

      1. 谢谢,已解决,请求的接口有一个302跳转导致cookie丢失。
        参考链接:https://colobu.com/2017/04/19/go-http-redirect/

  4. 这个框架支持http2.0吗

    1. 暂时不支持, 可以去github提下, 我也觉得很重要的一个功能, 强哥说关注的人不多. 

  5. ctx这个参数比较懵, 为啥需要传递个ctx. 主要用处是啥. 能不能不传递. 
    在啥情况需要gctx.New()?
    1. 我记得文档里面说传递ctx是为了链路追踪

  6. 建议增加一个 自动重试 功能,  比如网络不稳定.