编程 Go语言中的`net/http`包,涵盖了HTTP请求和响应的基本概念

2024-11-19 09:48:17 +0800 CST views 794

概述

net/http 包可以处理 HTTP 协议,包括 HTTP 服务器和 HTTP 客户端。http 包主要由五个部分组成:

  • Request:HTTP 请求对象
  • Response:HTTP 响应对象
  • Client:HTTP 客户端
  • Server:HTTP 服务器
  • Handler:HTTP 请求处理程序

最简单的使用

http 包提供了对应于每个 HTTP 动词的函数来发送 HTTP 请求,当不需要对请求进行详细定制时,可以直接使用它们。例如:

resp, err := http.Get("http://example.com/") // GET 请求

resp, err := http.Post("http://example.com/", "application/json", body) // POST 请求

resp, err := http.PostForm("http://example.com/", url.Values{"foo": "bar"}) // 提交表单

HTTP 请求和响应

HTTP 作为通信协议,通过报文传递信息。报文分为请求报文和响应报文,在 http 包中,分别用 RequestResponse 对象进行抽象。

Request

可以通过 NewRequest 创建一个 Request 对象,方法声明如下,需要传入 HTTP 方法、URL 以及报文体进行初始化:

func NewRequest(method, url string, body io.Reader) (*Request, error)

Request 对象主要用于存储请求数据,其结构如下:

type Request struct {
    Method string         // HTTP 方法
    URL    *url.URL       // URL
    Header Header         // 报文头
    Body   io.ReadCloser  // 报文体
    Host   string         // 主机名
    // 其他字段...
}

可以看到 Request 对象可以对请求报文的各个方面进行设置,此外,Request 也提供了一些方法对这些属性进行访问和修改,详细文档可见 Request

Response

Request 对象类似,Response 也是一个数据对象,拥有多个字段来描述 HTTP 响应。需要注意的是 Response 对象引用了当前的 Request 对象。Response 的声明如下:

type Response struct {
    Status        string         // HTTP 状态 "200 OK"
    StatusCode    int            // 状态码 200
    Header        Header         // 响应报文头
    Body          io.ReadCloser  // 响应报文体
    ContentLength int64          // 报文长度
    Request       *Request       // 对应的请求对象
    // 其他字段...
}

Client

在第一节中的 GETPOST 等函数是通过绑定到默认 Client 实现的。你也可以创建自己的 Client 对象。要通过 Client 发出 HTTP 请求,可以先初始化一个 Client 对象,然后发出请求。例如,下面的程序访问 Google:

package main

import (
    "net/http"
    "fmt"
)

func main() {
    client := http.Client{}
    res, err := client.Get("http://www.google.com")
    if err != nil {
        fmt.Println("Error:", err)
        return
    }
    fmt.Println("Response Status:", res.Status)
}

对于常用 HTTP 动词,Client 对象提供了对应的函数处理:

func (c *Client) Get(url string) (resp *Response, err error)

func (c *Client) Post(url, contentType string, body io.Reader) (resp *Response, err error)

func (c *Client) PostForm(url string, data url.Values) (resp *Response, err error)

但是在很多情况下,需要对报文头、Cookies 等进行定制,上述方法不能满足需求。因此,Client 对象提供了一个 Do 方法,通过传入一个 Request 对象实现请求的定制化。方法声明如下:

func (c *Client) Do(req *Request) (resp *Response, err error)

下面是一个简单的配置实例:

package main

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

func main() {
    req, err := http.NewRequest(http.MethodGet, "http://www.baidu.com", nil)
    if err != nil {
        fmt.Println(err.Error())
        return
    }
    req.Header.Set("Cookie", "name=foo")
    req.Header.Set("Content-Type", "application/x-www-form-urlencoded")

    client := http.Client{}
    res, err := client.Do(req)
    if err != nil {
        fmt.Println(err.Error())
        return
    }
    defer res.Body.Close()

    body, err := ioutil.ReadAll(res.Body)
    if err != nil {
        fmt.Println(err.Error())
        return
    }

    fmt.Println(string(body))
}

Server

http 包不仅可以发送 HTTP 请求,还可以创建 HTTP 服务器,对外提供访问服务。可以通过 ListenAndServe 方法创建一个 HTTP 服务:

package main

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

func EchoServer(w http.ResponseWriter, req *http.Request) {
    body, err := io.ReadAll(req.Body)
    if err != nil {
        http.Error(w, "Unable to read body", http.StatusBadRequest)
        return
    }
    w.Write(body)
}

func main() {
    http.HandleFunc("/echo/", EchoServer)
    log.Fatal(http.ListenAndServe(":8080", nil))
}

在 Server 模块中,有两个重要的概念:URLHandler。前者是访问的路径,后者是对应的处理函数。Server 需要完成从 URLHandler 的映射。在 http 包中的默认实现是 DefaultServeMux,每个 Handler 需要通过 HandleFunc 进行注册。

HTTP 方法和状态码

除了上述内容外,http 包还定义了一系列常量用于表示 HTTP 动词和返回状态码,详情可见 constants


这个版本对原内容进行了结构优化,并删除了不必要的细节,使其更加简洁易读。

复制全文 生成海报 Go语言 网络编程 HTTP协议

推荐文章

解决 PHP 中的 HTTP 请求超时问题
2024-11-19 09:10:35 +0800 CST
rangeSlider进度条滑块
2024-11-19 06:49:50 +0800 CST
一个数字时钟的HTML
2024-11-19 07:46:53 +0800 CST
2025年,小程序开发到底多少钱?
2025-01-20 10:59:05 +0800 CST
Roop是一款免费开源的AI换脸工具
2024-11-19 08:31:01 +0800 CST
npm速度过慢的解决办法
2024-11-19 10:10:39 +0800 CST
PHP来做一个短网址(短链接)服务
2024-11-17 22:18:37 +0800 CST
前端如何给页面添加水印
2024-11-19 07:12:56 +0800 CST
html文本加载动画
2024-11-19 06:24:21 +0800 CST
JavaScript 上传文件的几种方式
2024-11-18 21:11:59 +0800 CST
Vue3中如何处理SEO优化?
2024-11-17 08:01:47 +0800 CST
Vue3中的组件通信方式有哪些?
2024-11-17 04:17:57 +0800 CST
HTML和CSS创建的弹性菜单
2024-11-19 10:09:04 +0800 CST
程序员茄子在线接单