ZetCode

Go http 客户端

最后修改时间 2024 年 4 月 11 日

在本文中,我们展示了如何在 Golang 中使用 net/http 创建 HTTP 请求。HTTP 客户端发送 HTTP 请求并接收由 URL 标识的资源的 HTTP 响应。

HTTP

超文本传输协议(Hypertext Transfer Protocol (HTTP))是一种用于分布式、协作式、超媒体信息系统的应用层协议。HTTP 协议是万维网数据通信的基础。

Go net/http

net/http 包包含用于创建 HTTP 客户端和服务器的工具。可以使用 http.Gethttp.Posthttp.PostFormhttp.Head 函数轻松创建 HTTP 请求。

要设置 HTTP 设置,例如标题或重定向策略,我们按以下方式创建客户端

client := &http.Client{
    CheckRedirect: redirectPolicyFunc,
}

resp, err := client.Get("http://example.com")

响应体必须在末尾关闭

defer resp.Body.Close()

Go http 客户端状态码

HTTP 响应状态码指示特定的 HTTP 请求是否已成功完成。响应分为五类

status.go
package main

import (
    "fmt"
    "log"
    "net/http"
)

func main() {

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

    if err != nil {

        log.Fatal(err)
    }

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

此示例创建一个 GET 请求到一个小型网站。我们获取请求的状态码。

fmt.Println(resp.Status)
fmt.Println(resp.StatusCode)

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

Go http 客户端 GET 请求

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

get_req.go
package main

import (
    "fmt"
    "io/ioutil"
    "log"
    "net/http"
)

func main() {

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

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

    defer resp.Body.Close()

    body, err := ioutil.ReadAll(resp.Body)

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

    fmt.Println(string(body))
}

我们向 webcode.me 网页发出 GET 请求。

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

使用 Get 函数发出 GET 请求。

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

我们检查错误。

defer resp.Body.Close()

客户端在完成后必须关闭响应体。

body, err := ioutil.ReadAll(resp.Body)

我们使用 ReadAll 读取响应体的内容。

fmt.Println(string(body))

我们将收到的数据打印到控制台。

$ go run get_req.go
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="format.css">
    <title>My html page</title>
</head>
<body>
...

Go http 客户端 HEAD 请求

HTTP HEAD 方法请求如果使用 HTTP GET 方法请求指定资源会返回的头部信息。

head_req.go
package main

import (
    "fmt"
    "log"
    "net/http"
)

func main() {

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

    if err != nil {

        log.Fatal(err)
    }

    for k, v := range resp.Header {

        fmt.Printf("%s %s\n", k, v)
    }
}

此示例使用 http.Head 发出 HEAD 请求,并打印响应头部的所有数据。

$ go run head_req.go
Content-Length [394]
Last-Modified [Sun, 23 Jan 2022 10:39:25 GMT]
Connection [keep-alive]
Etag ["61ed305d-18a"]
Accept-Ranges [bytes]
Server [nginx/1.6.2]
Date [Mon, 14 Feb 2022 13:50:22 GMT]
Content-Type [text/html]

User-Agent 头部

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

user_agent.go
package main

import (
    "fmt"
    "io/ioutil"
    "log"
    "net/http"
    "time"
)

func main() {

    c := http.Client{Timeout: time.Duration(3) * time.Second}

    req, err := http.NewRequest("GET", "http://webcode.me/ua.php", nil)

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

    req.Header.Add("User-Agent", "Go program")
    resp, err := c.Do(req)

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

    defer resp.Body.Close()

    body, err := ioutil.ReadAll(resp.Body)

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

    fmt.Println(string(body))
}

此示例为其 GET 请求设置了 User-Agent 头部。所请求的资源只是返回客户端的 User-Agent 字符串。

c := http.Client{Timeout: time.Duration(3) * time.Second}

我们使用 3 秒的超时时间创建 http 客户端。

req, err := http.NewRequest("GET", "http://webcode.me/ua.php", nil)

使用 http.NewRequest 创建新请求。

req.Header.Add("User-Agent", "Go program") 

我们将 User-Agent 头部添加到请求中。

$ go run user_agent.go 
Go program

Go http.PostForm

HTTP POST 方法将数据发送到服务器。

http.PostForm 向指定 URL 发出 POST 请求,将数据的键值对 URL 编码为请求体。Content-Type 头部被设置为 application/x-www-form-urlencoded

post_form.go
package main

import (
    "fmt"
    "io/ioutil"
    "log"
    "net/http"
    "net/url"
)

func main() {

    resp, err := http.PostForm("https://httpbin.org/post",
        url.Values{"name": {"John Doe"}, "message": {"Hey!"}})

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

    defer resp.Body.Close()
    body, err := ioutil.ReadAll(resp.Body)

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

    fmt.Println(string(body))
}

在示例中,我们向 https://httpbin.org/post 网站发送 POST 请求,这是一个在线的开发者测试服务。

$ go run post_form.go 
{
  "args": {}, 
  "data": "", 
  "files": {}, 
  "form": {
    "message": "Hey!", 
    "name": "John Doe"
  }, 
  "headers": {
    "Accept-Encoding": "gzip", 
    "Content-Length": "28", 
    "Content-Type": "application/x-www-form-urlencoded", 
    "Host": "httpbin.org", 
    "User-Agent": "Go-http-client/2.0", 
    "X-Amzn-Trace-Id": "Root=1-620a63eb-5b49f82c137a95e06bad94e3"
  }, 
  "json": null, 
  "origin": "188.167.250.179", 
  "url": "https://httpbin.org/post"
}

来源

Go net/http 包 - 参考

在本文中,我们创建了 Go 的 GET 和 POST 请求。

作者

我的名字是 Jan Bodnar,我是一名充满热情的程序员,拥有丰富的编程经验。我从 2007 年开始撰写编程文章。迄今为止,我已撰写了 1,400 多篇文章和 8 本电子书。我在编程教学方面拥有十多年的经验。

列出所有 Go 教程