Go语言的创建HTTP客户端

本文通过示例介绍了如何使用curl工具理解HTTP请求与响应的过程,并演示了如何利用Go语言进行GET和POST请求,包括自定义客户端、调试请求等高级操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

超文本传输协议(Hypertext Transfer Protocol,HTTP)

理解HTTP

要理解HTTP请求的结构,一种不错的方式是使用curl。输入命令行如下:

curl -s -o /dev/null -v http://google.com

运行结果如下:

*   Trying 172.217.160.78:80...
* Connected to google.com (172.217.160.78) port 80 (#0)
> GET / HTTP/1.1
> Host: google.com
> User-Agent: curl/7.77.0
> Accept: */*
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 301 Moved Permanently
< Location: http://www.google.com/
< Content-Type: text/html; charset=UTF-8
< Date: Wed, 26 Jan 2022 12:07:41 GMT
< Expires: Fri, 25 Feb 2022 12:07:41 GMT
< Cache-Control: public, max-age=2592000
< Server: gws
< Content-Length: 219
< X-XSS-Protection: 0
< X-Frame-Options: SAMEORIGIN
< 
{ [219 bytes data]
* Connection #0 to host google.com left intact

在verbose模式下的curl描述服务器和客户端之间传输的多个请求响应。其中的日志详细说明了发出的请求和收到的响应,对其解读如下。

以字符>打头的行描述了客户端发出的请求。

以字符<打头的行描述收到的响应。

请求的详细信息描述了随请求发送的一些报头,这些报头向服务器提供了一些有关客户端的信息。

响应详细描述了一些报头,这些报头指出了响应的内容类型、长度和发送时间。

发出GET请求

Go语言在net/http包中提供了一个快捷方式,可用于发出简单的GET请求。

GET请求,程序清单如下:

package main

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

func main() {
	response, err := http.Get("https://ifconfig.io")
	if err != nil {
		log.Fatal(err)
	}
	defer response.Body.Close()
	body, err := ioutil.ReadAll(response.Body)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%s", body)
}

运行结果如下:

39.187.125.38

发出POST请求

POST请求,程序清单如下:

package main

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

func main() {
	postData:=strings.NewReader(`{"some":"json"}`)
  response, err:=http.Post("https://httpbin.org/post","application/json",postData)
  if err!=nil{
    log.Fatal(err)
  }
  defer response.Body.Close()
	body, err := ioutil.ReadAll(response.Body)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%s", body)
}

运行结果如下:

{
  "args": {}, 
  "data": "{\"some\":\"json\"}", 
  "files": {}, 
  "form": {}, 
  "headers": {
    "Accept-Encoding": "gzip", 
    "Content-Length": "15", 
    "Content-Type": "application/json", 
    "Host": "httpbin.org", 
    "User-Agent": "Go-http-client/2.0", 
    "X-Amzn-Trace-Id": "Root=1-61f13d73-0184660a5ffb645c019256f7"
  }, 
  "json": {
    "some": "json"
  }, 
  "origin": "39.187.125.38", 
  "url": "https://httpbin.org/post"
}

进一步控制HTTP请求

使用自定义客户端,程序清单如下:

package main

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

func main() {
	client := &http.Client{}
	request, err := http.NewRequest("GET", "https://ifconfig.co", nil)
	if err != nil {
		log.Fatal(err)
	}
	response, err := client.Do(request)
	defer response.Body.Close()
	body, err := ioutil.ReadAll(response.Body)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%s", body)
}

运行结果如下:

39.185.200.242

调试HTTP请求

调试请求,程序清单如下:

package main

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

func main() {
	debug := os.Getenv("DEBUG")
	client := &http.Client{}
	request, err := http.NewRequest("GET", "http://ifconfig.co", nil)
	if err != nil {
		log.Fatal(err)
	}
	if debug == "1" {
		debugRequest, err := httputil.DumpRequestOut(request, true)
		if err != nil {
			log.Fatal(err)
		}
		fmt.Printf("%s", debugRequest)
	}
	response, err := client.Do(request)
	defer response.Body.Close()
	if debug == "1" {
		debugResponse, err := httputil.DumpResponse(response, true)
		if err != nil {
			log.Fatal(err)
		}
		fmt.Printf("%s", debugResponse)
	}
	body, err := ioutil.ReadAll(response.Body)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%s\n", body)
}

运行结果如下:

39.185.200.242

输入命令行如下:

DEBUG=1 go run main.go

如windows环境下,输入两行命令行,分别是“set DEBUG=1”和“go run main.go”

运行结果如下:

GET / HTTP/1.1
Host: ifconfig.co
User-Agent: Go-http-client/1.1
Accept-Encoding: gzip

HTTP/1.1 200 OK
Content-Length: 15
Alt-Svc: h3=":443"; ma=86400, h3-29=":443"; ma=86400
Cf-Cache-Status: DYNAMIC
Cf-Ray: 6d830912ef3713d8-SEA
Connection: keep-alive
Content-Type: text/plain; charset=utf-8
Date: Fri, 04 Feb 2022 09:57:33 GMT
Nel: {"success_fraction":0,"report_to":"cf-nel","max_age":604800}
Report-To: {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v3?s=jQxqcAb03W4fzDSRbyYDDT4ne%2F2U6UO6NF9DS39Zi01V6jRTkfE%2Fd1%2B85TeOq5%2B%2BsGcFLooqenMN2%2BPARV612f6XqmU0c7H4vLtlHZijifP3822qQBCCDdFaqWjzuw%3D%3D"}],"group":"cf-nel","max_age":604800}
Server: cloudflare

39.185.200.242
39.185.200.242

要请求JSON数据,可修改客户端,设置一个请求JSON的报头。如下:

request.Header.Add("Accept","application/json")

处理超时

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值