跳转到主要内容

标签(标签)

资源精选(342) Go开发(108) Go语言(103) Go(99) angular(82) LLM(75) 大语言模型(63) 人工智能(53) 前端开发(50) LangChain(43) golang(43) 机器学习(39) Go工程师(38) Go程序员(38) Go开发者(36) React(33) Go基础(29) Python(24) Vue(22) Web开发(20) Web技术(19) 精选资源(19) 深度学习(19) Java(18) ChatGTP(17) Cookie(16) android(16) 前端框架(13) JavaScript(13) Next.js(12) 安卓(11) 聊天机器人(10) typescript(10) 资料精选(10) NLP(10) 第三方Cookie(9) Redwoodjs(9) LLMOps(9) Go语言中级开发(9) 自然语言处理(9) PostgreSQL(9) 区块链(9) mlops(9) 安全(9) 全栈开发(8) ChatGPT(8) OpenAI(8) Linux(8) AI(8) GraphQL(8) iOS(8) 软件架构(7) Go语言高级开发(7) AWS(7) C++(7) 数据科学(7) whisper(6) Prisma(6) 隐私保护(6) RAG(6) JSON(6) DevOps(6) 数据可视化(6) wasm(6) 计算机视觉(6) 算法(6) Rust(6) 微服务(6) 隐私沙盒(5) FedCM(5) 语音识别(5) Angular开发(5) 快速应用开发(5) 提示工程(5) Agent(5) LLaMA(5) 低代码开发(5) Go测试(5) gorm(5) REST API(5) 推荐系统(5) WebAssembly(5) GameDev(5) CMS(5) CSS(5) machine-learning(5) 机器人(5) 游戏开发(5) Blockchain(5) Web安全(5) Kotlin(5) 低代码平台(5) 机器学习资源(5) Go资源(5) Nodejs(5) PHP(5) Swift(5) 智能体(4) devin(4) Blitz(4) javascript框架(4) Redwood(4) GDPR(4) 生成式人工智能(4) Angular16(4) Alpaca(4) 编程语言(4) SAML(4) JWT(4) JSON处理(4) Go并发(4) kafka(4) 移动开发(4) 移动应用(4) security(4) 隐私(4) spring-boot(4) 物联网(4) nextjs(4) 网络安全(4) API(4) Ruby(4) 信息安全(4) flutter(4) 专家智能体(3) Chrome(3) CHIPS(3) 3PC(3) SSE(3) 人工智能软件工程师(3) LLM Agent(3) Remix(3) Ubuntu(3) GPT4All(3) 软件开发(3) 问答系统(3) 开发工具(3) 最佳实践(3) RxJS(3) SSR(3) Node.js(3) Dolly(3) 移动应用开发(3) 低代码(3) IAM(3) Web框架(3) CORS(3) 基准测试(3) Go语言数据库开发(3) Oauth2(3) 并发(3) 主题(3) Theme(3) earth(3) nginx(3) 软件工程(3) azure(3) keycloak(3) 生产力工具(3) gpt3(3) 工作流(3) C(3) jupyter(3) 认证(3) prometheus(3) GAN(3) Spring(3) 逆向工程(3) 应用安全(3) Docker(3) Django(3) R(3) .NET(3) 大数据(3) Hacking(3) 渗透测试(3) C++资源(3) Mac(3) 微信小程序(3) Python资源(3) JHipster(3) 大型语言模型(2) 语言模型(2) 可穿戴设备(2) JDK(2) SQL(2) Apache(2) Hashicorp Vault(2) Spring Cloud Vault(2) Go语言Web开发(2) Go测试工程师(2) WebSocket(2) 容器化(2) AES(2) 加密(2) 输入验证(2) ORM(2) Fiber(2) Postgres(2) Gorilla Mux(2) Go数据库开发(2) 模块(2) 泛型(2) 指针(2) HTTP(2) PostgreSQL开发(2) Vault(2) K8s(2) Spring boot(2) R语言(2) 深度学习资源(2) 半监督学习(2) semi-supervised-learning(2) architecture(2) 普罗米修斯(2) 嵌入模型(2) productivity(2) 编码(2) Qt(2) 前端(2) Rust语言(2) NeRF(2) 神经辐射场(2) 元宇宙(2) CPP(2) 数据分析(2) spark(2) 流处理(2) Ionic(2) 人体姿势估计(2) human-pose-estimation(2) 视频处理(2) deep-learning(2) kotlin语言(2) kotlin开发(2) burp(2) Chatbot(2) npm(2) quantum(2) OCR(2) 游戏(2) game(2) 内容管理系统(2) MySQL(2) python-books(2) pentest(2) opengl(2) IDE(2) 漏洞赏金(2) Web(2) 知识图谱(2) PyTorch(2) 数据库(2) reverse-engineering(2) 数据工程(2) swift开发(2) rest(2) robotics(2) ios-animation(2) 知识蒸馏(2) 安卓开发(2) nestjs(2) solidity(2) 爬虫(2) 面试(2) 容器(2) C++精选(2) 人工智能资源(2) Machine Learning(2) 备忘单(2) 编程书籍(2) angular资源(2) 速查表(2) cheatsheets(2) SecOps(2) mlops资源(2) R资源(2) DDD(2) 架构设计模式(2) 量化(2) Hacking资源(2) 强化学习(2) flask(2) 设计(2) 性能(2) Sysadmin(2) 系统管理员(2) Java资源(2) 机器学习精选(2) android资源(2) android-UI(2) Mac资源(2) iOS资源(2) Vue资源(2) flutter资源(2) JavaScript精选(2) JavaScript资源(2) Rust开发(2) deeplearning(2) RAD(2)

介绍

当一个程序需要与另一个程序通信时,许多开发人员会使用HTTP。Go的优势之一是其标准库的广度,HTTP也不例外。Go-net/http包不仅支持创建http服务器,还可以作为客户端发出http请求。

在本教程中,您将创建一个向HTTP服务器发出多种类型HTTP请求的程序。首先,您将使用默认的GoHTTP客户端发出GET请求。然后,您将增强您的程序,以使用body发出POST请求。最后,您将自定义POST请求以包含HTTP头,并添加一个超时,如果您的请求耗时过长,则会触发该超时。

先决条件

要遵循本教程,您需要:

  • 安装1.16或更高版本。要设置此设置,请遵循操作系统的“如何安装Go”教程。
  • 在Go中创建HTTP服务器的经验,可以在教程“如何在Go上创建HTTP服务器”中找到。
  • 熟悉goroutines和阅读频道。有关更多信息,请参阅教程“如何在Go中并发运行多个函数”。
  • 建议了解HTTP请求的组成和发送方式。

提出GET请求

Go-net/http包有几种不同的方式将其用作客户端。您可以使用具有HTTP等功能的通用全局HTTP客户端。Get只需一个URL和一个正文就可以快速发出HTTP Get请求,或者您可以创建一个HTTP。请求开始定制个别请求的某些方面。在本节中,您将使用http创建一个初始程序。获取一个HTTP请求,然后将其更新为使用HTTP。使用默认HTTP客户端请求。

使用 http.Get 提出请求

在程序的第一次迭代中,您将使用http。Get函数向程序中运行的HTTP服务器发出请求。http:。Get函数很有用,因为您不需要在程序中进行任何其他设置来发出请求。如果您需要快速请求,请使用http。获取可能是最好的选择。

要开始创建程序,您需要一个目录来保存程序的目录。在本教程中,您将使用名为projects的目录。

首先,创建项目目录并导航到它:

  1. mkdir projects
  2. cd projects

接下来,为项目创建目录并导航到它。在这种情况下,请使用目录httpclient:

  1. mkdir httpclient
  2. cd httpclient

在httpclient目录中,使用nano或您最喜欢的编辑器打开main.go文件

在main.go文件,首先添加以下行:

package main

import (
	"errors"
	"fmt"
	"net/http"
	"os"
	"time"
)

const serverPort = 3333

 

您可以添加包名称main,以便将程序编译为可以运行的程序,然后在该程序中将使用的各种包中包含一个import语句。之后,创建一个名为serverPort的常量,其值为3333,将用作HTTP服务器正在侦听的端口和HTTP客户端将连接的端口。

接下来,在main中创建一个main函数。go文件并设置goroutine以启动HTTP服务器:

func main() {
	go func() {
		mux := http.NewServeMux()
		mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
			fmt.Printf("server: %s /\n", r.Method)
		})
		server := http.Server{
			Addr:    fmt.Sprintf(":%d", serverPort),
			Handler: mux,
		}
		if err := server.ListenAndServe(); err != nil {
			if !errors.Is(err, http.ErrServerClosed) {
				fmt.Printf("error running http server: %s\n", err)
			}
		}
	}()

	time.Sleep(100 * time.Millisecond)

 

HTTP服务器已设置为使用fmt。Printf可在请求根/路径时打印有关传入请求的信息。它还设置为侦听serverPort。最后,一旦启动服务器goroutine,您的程序就会占用时间。短时间睡眠。这个睡眠时间允许HTTP服务器有足够的时间启动并开始响应下一个请求。

现在,同样在主函数中,使用fmt设置请求URL。Sprintf将http://localhost主机名和服务器正在侦听的serverPort值。然后,使用http。获取对该URL的请求,如下所示:

...
	requestURL := fmt.Sprintf("http://localhost:%d", serverPort)
	res, err := http.Get(requestURL)
	if err != nil {
		fmt.Printf("error making http request: %s\n", err)
		os.Exit(1)
	}

	fmt.Printf("client: got response!\n")
	fmt.Printf("client: status code: %d\n", res.StatusCode)
}

 

HTTP服务器已设置为使用fmt。Printf可在请求根/路径时打印有关传入请求的信息。它还设置为侦听serverPort。最后,一旦启动服务器goroutine,您的程序就会占用时间。短时间睡眠。这个睡眠时间允许HTTP服务器有足够的时间启动并开始响应下一个请求。

现在,同样在主函数中,使用fmt设置请求URL。Sprintf将http://localhost主机名和服务器正在侦听的serverPort值。然后,使用http。获取对该URL的请求,如下所示:

  1. go run main.go

 

您将看到以下输出:


 

Output

server: GET /

client: got response!

client: status code: 200

 

在输出的第一行,服务器打印它从客户机收到了一个GET请求,请求/路径。然后,下面两行表示客户机从服务器返回了一个响应,并且该响应的状态代码是200。

http:。Get函数对于快速HTTP请求很有用,如您在本节中所做的请求。然而,http。请求提供了更广泛的选项来定制您的请求。

使用http.Request提出请求

与http相反。获取,http。请求函数为您提供了对请求的更大控制,而不仅仅是HTTP方法和被请求的URL。您还不会使用其他功能,而是使用http。现在请求,您将能够在本教程稍后添加这些自定义设置。

在您的代码中,第一个更新是更改HTTP服务器处理程序,以使用fmt.Fprintf返回假JSON数据响应。如果这是一个完整的HTTP服务器,那么该数据将使用Go的encoding/json包生成。如果您想了解有关在围棋中使用JSON的更多信息,我们的“如何在围棋里使用JSON”教程提供了。此外,您还需要将io/ioutil作为导入包含进来,以便在本次更新中稍后使用。

现在,打开主管道。再次转到文件并更新您的程序以开始使用http。请求如下:

package main

import (
	...
	"io/ioutil"
	...
)

...

func main() {
	...
	mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		fmt.Printf("server: %s /\n", r.Method)
		fmt.Fprintf(w, `{"message": "hello!"}`)
	})
	...

现在,更新您的HTTP请求代码,以代替使用HTTP。要向服务器发出请求,请使用http。NewRequest和http。DefaultClient的Do方法:

...
	requestURL := fmt.Sprintf("http://localhost:%d", serverPort)
	req, err := http.NewRequest(http.MethodGet, requestURL, nil)
	if err != nil {
		fmt.Printf("client: could not create request: %s\n", err)
		os.Exit(1)
	}

	res, err := http.DefaultClient.Do(req)
	if err != nil {
		fmt.Printf("client: error making http request: %s\n", err)
		os.Exit(1)
	}

	fmt.Printf("client: got response!\n")
	fmt.Printf("client: status code: %d\n", res.StatusCode)

	resBody, err := ioutil.ReadAll(res.Body)
	if err != nil {
		fmt.Printf("client: could not read response body: %s\n", err)
		os.Exit(1)
	}
	fmt.Printf("client: response body: %s\n", resBody)
}

在此更新中,您使用http。NewRequest函数生成http。请求值,或在无法创建值时处理错误。与http不同。不过,Get函数是http。NewRequest函数不会立即向服务器发送HTTP请求。由于它不会立即发送请求,因此您可以在发送请求之前对其进行任何更改。

一旦http。创建和配置请求时,使用http的Do方法。DefaultClient将请求发送到服务器。http:。DefaultClient值是Go的默认HTTP客户端,与您在HTTP.Get中使用的相同。不过,这一次,您直接使用它来告诉它发送您的http.Request。HTTP客户端的Do方法返回从HTTP接收到的相同值。Get函数,以便您可以以相同的方式处理响应。

打印请求结果后,使用ioutil。ReadAll函数读取HTTP响应的正文。身体是一个io。ReadCloser值,io的组合。阅读器和io。更近一些,这意味着你可以使用任何可以从io读取的东西来读取身体的数据。读取器值。ioutil。ReadAll函数很有用,因为它将从io读取。读取器,直到它到达数据末尾或遇到错误。然后,它将返回数据作为[]字节值,您可以使用fmt打印。Printf或它遇到的错误值。

要运行更新的程序,请保存更改并使用go-run命令:

  1. go run main.go

 

这一次,您的输出应该与之前非常相似,但有一点:


 

Output

server: GET /

client: got response!

client: status code: 200

client: response body: {"message": "hello!"}

在第一行中,您可以看到服务器仍在接收对/path的GET请求。客户端还从服务器接收200响应,但它也在读取和打印服务器响应的正文。在更复杂的程序中,您可以接受{“message”:“hello!”}值,并使用encoding/JSON包将其处理为JSON。

在本节中,您使用HTTP服务器创建了一个程序,并以各种方式向其发出HTTP请求。首先,您使用了http。Get函数仅使用服务器的URL向服务器发出Get请求。然后,您将程序更新为使用http。NewRequest创建http。请求值。创建后,使用Go的默认HTTP客户端HTTP的Do方法。DefaultClient,以发出请求并打印http。输出的响应主体。

不过,HTTP协议不仅仅使用GET请求在程序之间进行通信。当您想从其他程序接收信息时,GET请求很有用,但当您想将信息从程序发送到服务器时,可以使用另一种HTTP方法POST方法。

发送POST请求

在REST API中,GET请求仅用于从服务器检索信息,因此为了让您的程序完全参与REST API,您的程序还需要支持发送POST请求。POST请求几乎与GET请求相反,客户端将数据发送到请求主体中的服务器。

在本节中,您将更新程序以将请求作为POST请求而不是GET请求发送。您的POST请求将包括一个请求主体,您将更新服务器以打印出有关您从客户端发出的请求的更多信息。

要开始进行这些更新,请打开主菜单。转到文件并添加一些您将要使用的新包到导入语句中:

...

import (
    "bytes"
    "errors"
    "fmt"
    "io/ioutil"
    "net/http"
    "os"
    "strings"
    "time"
)

...

然后,更新您的服务器处理程序函数,以打印有关传入请求的各种信息,例如查询字符串值、头值和请求正文:

...
  mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
      fmt.Printf("server: %s /\n", r.Method)
      fmt.Printf("server: query id: %s\n", r.URL.Query().Get("id"))
      fmt.Printf("server: content-type: %s\n", r.Header.Get("content-type"))
      fmt.Printf("server: headers:\n")
      for headerName, headerValue := range r.Header {
          fmt.Printf("\t%s = %s\n", headerName, strings.Join(headerValue, ", "))
      }

      reqBody, err := ioutil.ReadAll(r.Body)
      if err != nil {
             fmt.Printf("server: could not read request body: %s\n", err)
      }
      fmt.Printf("server: request body: %s\n", reqBody)

      fmt.Fprintf(w, `{"message": "hello!"}`)
  })
...

在服务器HTTP请求处理程序的更新中,您添加了一些更有用的fmt.Printf语句,以查看有关传入请求的信息。您使用r.URL.Query().Get获取名为id的查询字符串值,使用r.Header.Get获得名为content-type的头的值。您还可以使用带有r.Header的for循环来打印服务器接收到的每个HTTP头的名称和值。如果您的客户机或服务器没有按照预期的方式运行,则此信息对于解决问题非常有用。最后,您还使用ioutil.ReadAll函数在r.body中读取HTTP请求的正文。

更新服务器处理程序函数后,更新主函数的请求代码,以便它发送带有请求主体的POST请求:

...
 time.Sleep(100 * time.Millisecond)
    
 jsonBody := []byte(`{"client_message": "hello, server!"}`)
 bodyReader := bytes.NewReader(jsonBody)

 requestURL := fmt.Sprintf("http://localhost:%d?id=1234", serverPort)
 req, err := http.NewRequest(http.MethodPost, requestURL, bodyReader)
...

在对主函数请求的更新中,您正在定义的一个新值是jsonBody值。在本例中,该值表示为[]字节而不是标准字符串,因为如果您使用encoding/json包对json数据进行编码,它将返回[]字节,而不是字符串。

下一个值bodyReader是字节。包装jsonBody数据的读取器。一个http。请求正文要求值为io。Reader和jsonBody的[]字节值不实现io。阅读器,所以您不能将其单独用作请求主体。字节。存在读取器值以提供该io。读取器接口,因此可以使用jsonBody值作为请求主体。

requestURL值也被更新为包括id=1234查询字符串值,主要是为了显示查询字符串值如何也可以与其他标准URL组件一起包含在请求URL中。

最后,http。NewRequest函数调用被更新为使用带有http的POST方法。通过将最后一个参数从nil主体更新为bodyReader(JSON数据io.Reader)来包含请求主体。

保存更改后,可以使用go run运行程序:

go run main.go

由于您更新服务器以显示其他信息,输出将比以前更长:


 

Output

server: POST / 

server: query id: 1234 

server: content-type: 

server: headers: Accept-Encoding = gzip User-Agent = Go-http-client/1.1 Content-Length = 36 

server: request body: {"client_message": "hello, server!"} 

client: got response! 

client: status code: 200 

client: response body: {"message": "hello!"}

来自服务器的第一行显示您的请求现在作为POST请求传递到/path。第二行显示添加到请求URL的id查询字符串值的1234值。第三行显示了客户端发送的Content-Type头的值,该头在该请求中恰好为空。

第四行可能与上面看到的输出略有不同。在Go中,当您使用range迭代映射值时,无法保证映射值的顺序,因此您的r.headers头可能会以不同的顺序打印出来。根据您使用的Go版本,您可能还会看到与上面不同的User Agent版本。

最后,输出中的最后一个变化是服务器显示了从客户端接收到的请求主体。然后,服务器可以使用encoding/json包解析客户端发送的json数据并制定响应。

在本节中,您更新了程序以发送HTTP POST请求而不是GET请求。您还更新了程序,以发送一个请求正文,其中[]字节数据由bytes.Reader读取。最后,您更新了服务器处理程序函数,以打印出有关HTTP客户端正在发出的请求的更多信息。

通常,在HTTP请求中,客户端或服务器会告诉对方它在正文中发送的内容类型。正如您在上一个输出中看到的那样,您的HTTP请求没有包含Content-Type头来告诉服务器如何解释正文的数据。在下一节中,您将进行一些更新来定制HTTP请求,包括设置Content-Type头,让服务器知道您发送的数据类型。

自定义HTTP请求

随着时间的推移,HTTP请求和响应被用于在客户端和服务器之间发送更多种类的数据。在某一点上,HTTP客户端可能会认为他们从HTTP服务器接收的数据是HTML,并且很有可能是正确的。不过现在,它可以是HTML、JSON、音乐、视频或任何其他数据类型。为了提供有关通过HTTP发送的数据的更多信息,协议包括HTTP头,其中一个重要的头是Content-Type头。这个头告诉服务器(或客户端,取决于数据的方向)如何解释它正在接收的数据。

在本节中,您将更新程序以在HTTP请求上设置Content-Type头,以便服务器知道它正在接收JSON数据。您还将更新您的程序以使用除Go的默认HTTP之外的HTTP客户端。DefaultClient,以便您可以自定义发送请求的方式。

要进行这些更新,请打开主菜单。再次打开文件并更新主函数,如下所示:

...

  req, err := http.NewRequest(http.MethodPost, requestURL, bodyReader)
  if err != nil {
         fmt.Printf("client: could not create request: %s\n", err)
         os.Exit(1)
  }
  req.Header.Set("Content-Type", "application/json")

  client := http.Client{
     Timeout: 30 * time.Second,
  }

  res, err := client.Do(req)
  if err != nil {
      fmt.Printf("client: error making http request: %s\n", err)
      os.Exit(1)
  }

...

在此更新中,您可以访问http。使用req请求标头。Header,然后将请求的Content-Type头的值设置为application/json。application/json媒体类型在媒体类型列表中定义为json的媒体类型。这样,当服务器接收到您的请求时,它知道将主体解释为JSON,而不是XML。

下一个更新是创建自己的http。客户端变量中的客户端实例。在此客户端中,您将超时值设置为30秒。这一点很重要,因为它表示,向客户端发出的任何请求都将在30秒后放弃并停止尝试接收响应。Go的默认http。DefaultClient没有指定超时,因此如果您使用该客户端发出请求,它将等待直到收到响应、服务器断开连接或程序结束。如果您有许多请求像这样等待响应,那么您可能正在使用计算机上的大量资源。设置超时值可限制请求在您定义的时间之前等待的时间。

最后,您更新了请求,以使用客户端变量的Do方法。您不需要在此进行任何其他更改,因为您一直在http上调用Do。客户重视整个时间。Go的默认HTTP客户端HTTP。DefaultClient只是一个http。默认情况下创建的客户端。所以,当你调用http时。Get,函数正在为您调用Do方法,当您更新请求以使用http时。DefaultClient,您使用的是http。客户直接。现在唯一的区别是您创建了http。你这次使用的客户价值。

现在,保存文件并使用go-run运行程序:

go run main.go

您的输出应该与之前的输出非常相似,但包含有关内容类型的更多信息:

Output
server: POST /
server: query id: 1234
server: content-type: application/json
server: headers:
        Accept-Encoding = gzip
        User-Agent = Go-http-client/1.1
        Content-Length = 36
        Content-Type = application/json
server: request body: {"client_message": "hello, server!"}
client: got response!
client: status code: 200
client: response body: {"message": "hello!"}

您将看到来自服务器的内容类型值,以及客户端正在发送的内容类型标头。这就是为什么可以同时为JSON和XML API提供相同的HTTP请求路径。通过指定请求的内容类型,服务器和客户端可以对数据进行不同的解释。

不过,这个示例不会触发您配置的客户端超时。要查看当请求花费太长时间并且触发超时时会发生什么,请打开主窗口。去文件并添加时间。对HTTP服务器处理程序函数的睡眠函数调用。然后,腾出时间。睡眠持续时间超过指定的超时时间。在这种情况下,将其设置为35秒:

...

func main() {
    go func() {
        mux := http.NewServeMux()
        mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
            ...    
            fmt.Fprintf(w, `{"message": "hello!"}`)
            time.Sleep(35 * time.Second)
        })
        ...
    }()
    ...
}

现在,保存更改并使用go run运行程序:

go run main.go

当您这次运行它时,退出的时间将比以前长,因为它在HTTP请求完成后才会退出。由于添加了time.Sleep(35*time.Second),HTTP请求在达到30秒超时之前不会完成:

Output
server: POST /
server: query id: 1234
server: content-type: application/json
server: headers:
        Content-Type = application/json
        Accept-Encoding = gzip
        User-Agent = Go-http-client/1.1
        Content-Length = 36
server: request body: {"client_message": "hello, server!"}
client: error making http request: Post "http://localhost:3333?id=1234": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
exit status 1

在这个程序输出中,您可以看到服务器收到了请求并进行了处理,但当它到达HTTP处理程序函数的末尾时,您的时间就到了。睡眠功能调用是,它开始睡眠35秒。同时,HTTP请求的超时正在倒计时,并在HTTP请求完成之前达到30秒的限制。这将导致客户端。Do方法调用失败,上下文截止日期超过错误,因为请求的30秒截止日期已过。然后,您的程序使用os.Exit(1)退出,失败状态代码为1。

在本节中,您更新了程序,通过向HTTP请求添加Content-Type头来定制HTTP请求。您还更新了程序以创建新的http。客户端超时30秒,然后使用该客户端发出HTTP请求。您还通过添加时间测试了30秒超时。睡眠到HTTP请求处理程序。最后,您还了解了为什么使用自己的http很重要。如果您想避免许多请求可能永远处于空闲状态,请设置超时的客户端值。

结论

在本教程中,您使用HTTP服务器创建了一个新程序,并使用Go的net/HTTP包向该服务器发出HTTP请求。首先,您使用了http。Get函数使用Go的默认HTTP客户端向服务器发出Get请求。然后,您使用了http。带有http的NewRequest。DefaultClient的Do方法发出GET请求。接下来,您使用bytes.NewReader更新了请求,使其成为带有正文的POST请求。最后,您在http上使用了Set方法。Request's Header字段用于设置请求的Content-Type头,并通过创建自己的HTTP客户端而不是使用Go的默认客户端来设置请求持续时间的30秒超时。

net/http包不仅仅包括您在本教程中使用的功能。它还包括一个http。Post函数,可用于发出Post请求,类似于http。获取函数。该软件包还支持保存和检索cookie等功能。

文章链接