Golang使用Reqhttp客户端创建HTTP请求

GoReq教程展示了如何使用Reqhttp客户端创建HTTP请求。http客户端发送HTTP请求并从由URL标识的资源接收HTTP响应。

$ go version
go version go1.18.1 linux/amd64

我们使用Go版本1.18。

HTTP

超文本传输​​协议(HTTP)是分布式协作超媒体信息系统的应用协议。HTTP协议是万维网数据通信的基础。

要求

Req是一个具有很多功能的第三方HTTP客户端。它具有许多方便的功能,便于配置、调试和测试。

响应状态码

HTTP响应状态代码指示特定HTTP请求是否已成功完成。有五个组可用:

  • 信息响应(100-199)
  • 成功响应(200-299)
  • 重定向(300-399)
  • 客户端错误(400-499)
  • 服务器错误(500-599)
package main

import (
    "fmt"
    "log"

    "github.com/imroc/req/v3"
)

func main() {

    res, err := req.Get("http://webcode.me")

    if err != nil {
        log.Fatal(err)
    }

    fmt.Println(res.Status)
    fmt.Println(res.StatusCode)
}

该示例创建了一个对小型网站的GET请求。我们得到请求的状态码。

import (
    "fmt"
    "log"

    "github.com/imroc/req/v3"
)

我们导入req包。

res, err := req.Get("http://webcode.me")

我们使用Get生成GET请求。

fmt.Println(res.Status)
fmt.Println(res.StatusCode)

Status以字符串形式给出状态,以数字形式给出StatusCode

进入请求开发模式

使用DevMode函数,我们启用开发模式。在这种模式下,我们将HTTP命令、HTTP标头和响应自动打印到控制台。

package main

import (
    "log"

    "github.com/imroc/req/v3"
)

func main() {

    req.DevMode()

    _, err := req.Get("http://webcode.me")

    if err != nil {
        log.Fatal(err)
    }
}

我们在开发模式下创建一个简单的GET请求。

$ go run main.go
2022/05/31 12:39:14.685055 DEBUG [req] HTTP/1.1 GET http://webcode.me
GET / HTTP/1.1
Host: webcode.me
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) ...
Accept-Encoding: gzip

HTTP/1.1 200 OK
Server: nginx/1.6.2
Date: Tue, 31 May 2022 10:39:14 GMT
Content-Type: text/html
...

GoReqGET请求

以下示例在Req中创建一个简单的GET请求。

package main

import (
    "fmt"
    "log"

    "github.com/imroc/req/v3"
)

func main() {

    res, err := req.Get("http://webcode.me")

    if err != nil {
        log.Fatal(err)
    }

    fmt.Println(res)

    bytes, err := res.ToBytes()

    if err != nil {
        log.Fatal(err)
    }

    fmt.Println(string(bytes))
}

我们向webcode.me创建一个GET请求。

res, err := req.Get("http://webcode.me")

使用Get函数发出获取请求。

if err != nil {
    log.Fatal(err)
}

我们检查错误。

fmt.Println(res)

我们打印响应。

bytes, err := res.ToBytes()
...
fmt.Println(string(bytes))

或者,我们可以获取字节并将它们转换为字符串。

GoReqHEAD请求

如果使用HTTPGET方法请求指定的资源,则HTTPHEAD方法请求返回的标头。

package main

import (
    "fmt"
    "log"

    "github.com/imroc/req/v3"
)

func main() {

    res, err := req.Head("http://webcode.me")

    if err != nil {
        log.Fatal(err)
    }

    for k, v := range res.Header {
        fmt.Printf("%s %s\n", k, v)
    }
}

该示例使用Head发出HEAD请求,并打印响应标头中的所有键/值对。

$ go run main.go
Connection [keep-alive]
Etag ["61ed305d-18a"]
Content-Type [text/html]
Content-Length [394]
Last-Modified [Sun, 23 Jan 2022 10:39:25 GMT]
Server [nginx/1.6.2]
Date [Tue, 31 May 2022 10:50:54 GMT]
Accept-Ranges [bytes]

去请求用户代理

User-Agent请求标头是一个字符串,可让服务器和网络对等方识别请求用户代理的应用程序、操作系统、供应商和/或版本。

package main

import (
    "fmt"
    "log"

    "github.com/imroc/req/v3"
)

func main() {

    res, err := req.C().SetUserAgent("Go program").
        R().Get("http://webcode.me/ua.php")

    if err != nil {
        log.Fatal(err)
    }

    fmt.Println(res)
}

该示例使用SetUserAgent设置了一个User-Agent标头。请求的资源仅返回客户端的用户代理字符串。

res, err := req.C().SetUserAgent("Go program").
    R().Get("http://webcode.me/ua.php")

C是创建客户端的辅助函数,R是创建请求的辅助函数。

$ go run main.go 
Go program

查询参数

查询参数是统一资源定位器(URL)的一部分,它为指定的参数赋值。这是将数据发送到目标服务器的一种方式。

http://example.com/api/users?name=John%20Doe&occupation=gardener

查询参数在?之后指定特点。多个字段用&分隔。对特殊字符(例如空格)进行编码。在上面的字符串中,空格使用%20值进行编码。

package main

import (
    "fmt"
    "log"

    "github.com/imroc/req/v3"
)

func main() {

    res, err := req.C().R().Get("http://localhost:8080/hello?name=Peter")

    if err != nil {
        log.Fatal(err)
    }

    fmt.Println(res)
}

在示例中,我们将查询参数(name=Peter)添加到requestURL。或者,我们也可以使用请求的SetQueryParam函数。

为了测试示例,我们使用Echo框架创建了一个简单的服务器。

package main

import (
    "fmt"
    "net/http"

    "github.com/labstack/echo/v4"
)

func main() {

    e := echo.New()

    e.GET("/hello/:name/", func(c echo.Context) error {

        name := c.Param("name")
        msg := fmt.Sprintf("Hello %s!", name)
        return c.String(http.StatusOK, msg)
    })

    e.Logger.Fatal(e.Start(":8080"))
}

服务器处理请求,使用Param检索查询参数,并将消息返回给客户端。

路径参数

值可以通过查询参数或路径参数发送到服务器。path参数直接在URL路径中指定。

package main

import (
    "fmt"
    "log"

    "github.com/imroc/req/v3"
)

func main() {

    res, err := req.C().R().SetPathParam("name", "Peter").
        Get("http://localhost:8080/hello/{name}/")

    if err != nil {
        log.Fatal(err)
    }

    fmt.Println(res)
}

我们使用SetPathParam设置路径参数。

以下服务器示例处理带有路径变量的请求。

package main

import (
    "fmt"
    "net/http"

    "github.com/labstack/echo/v4"
)

func main() {

    e := echo.New()

    e.GET("/hello/:name/", func(c echo.Context) error {

        name := c.Param("name")
        msg := fmt.Sprintf("Hello %s!", name)
        return c.String(http.StatusOK, msg)
    })

    e.Logger.Fatal(e.Start(":8080"))
}

在服务器应用程序中,我们指定一个带有冒号字符的路径变量。我们通过Param获取该变量,构建一条消息并将其发送给客户端。

下载文件

以下示例下载一个二进制文件。

package main

import (
    "log"

    "github.com/imroc/req/v3"
)

func main() {

    client := req.C()

    url := "http://webcode.me/favicon.ico"

    _, err := client.R().SetOutputFile("favicon.ico").Get(url)

    if err != nil {
        log.Fatal(err)
    }
}

SetOutputFile函数设置响应主体将被下载到的文件。

上传文件

下一个示例上传一个二进制文件。

package main

import (
    "fmt"
    "log"

    "github.com/imroc/req/v3"
)

func main() {

    client := req.C()

    res, err := client.R().
        SetFile("file", "sid.png").
        Post("http://localhost:8080/upload")

    if err != nil {
        log.Fatal(err)
    }

    fmt.Println(res.Status)
}

SetFile函数设置了一个从文件路径到上传的多部分表单,自动从文件路径读取文件上传。

我们创建一个服务器来处理请求。

package main

import (
    "io"
    "net/http"
    "os"

    "github.com/labstack/echo/v4"
)

func upload(c echo.Context) error {

    file, err := c.FormFile("file")

    if err != nil {
        return err
    }

    src, err := file.Open()

    if err != nil {
        return err
    }

    defer src.Close()

    dst, err := os.Create(file.Filename)

    if err != nil {
        return err
    }

    defer dst.Close()

    if _, err = io.Copy(dst, src); err != nil {
        return err
    }

    return c.HTML(http.StatusOK, "File uploaded")
}

func main() {

    e := echo.New()

    e.POST("/upload", upload)

    e.Logger.Fatal(e.Start(":8080"))
}

服务器从请求中读取二进制数据并将其写入文件系统。

在本教程中,我们使用了ReqHTTP客户端。

列出所有Go教程。

赞(0) 打赏

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏