go-net/http标准库简明教程
前言
这两天懒了(bushi),快赶赶进度…
学习来源ChatGPT&&Go by example
本文会包括go的net/http标准库等基础知识!零基础小白请放心使用!
会有涉及计网的一点知识 (本人也正在cs144里挣扎)好难过下周要考计组和数据结构
长文预警!!!
Go的net/http标准库
基本概念
- net/http 是什么
它是 Go 标准库中用来处理 HTTP 请求和响应的模块,提供了构建 Web 服务的基本功能。 - 核心组件
- http.Server:表示 HTTP 服务器。
- http.Request:表示 HTTP 请求。
- http.ResponseWriter:用于构造 HTTP 响应。
- 路由与处理器:通过 Handler 接口和 ServeMux 路由器来实现。
示例
1 | package main |
运行后,访问 http://localhost:8080/Go,浏览器将显示:Hello, Go!
分块详细解释
启动HTTP服务器
http.ListenAndServe
用于启动HTTP服务器
1 | http.ListenAndServe(":8080", nil) |
请求处理器(Handler)
基本概念
Handler 是 Go 中处理 HTTP 请求的一个接口,它定义了以下方法:
1 | type Handler interface { |
- ResponseWriter:
用于构建和发送 HTTP 响应。
通过它可以设置状态码、响应头以及响应体。 - Request:
表示客户端的 HTTP 请求。
包含请求方法、URL、头信息、表单数据等。
总结:Handler 是处理 HTTP 请求并返回 HTTP 响应的逻辑核心。
实现Handler的两种方式
(1)实现http.Handler
接口
任何实现了ServeHTTP(w http.ResponseWriter, r *http.Request)
方法的类型都可以作为一个 Handler。
1 | package main |
在terminal中键入go run main.go
,然后在浏览器中键入http://localhost:8080/hello
,得到Hello, you've hit /hello
这个过程中,浏览器相当于客户端,浏览器通过url(http://localhost:8080/hello)构造出http请求,然后通过DNS解析把域名换算成ip地址,这样客户端知道目标服务器是谁,然后建立tcp/ip连接,再把构造出的http请求发送到目标服务器,在这里也就是把请求发送到本机的8080端口。Go程序相当于服务端,收到并解析http请求,把请求分发给注册的处理器handler。
在 Go 中,http 包提供了一个非常核心的功能:通过 HTTP 路由将不同的请求(通常是 HTTP 方法和路径的组合)指向特定的处理器(Handler)。这个过程叫做 注册。
(2)使用 http.HandlerFunc
Go 提供了一个便利的方法,可以将普通函数直接用作 Handler。这是通过类型 http.HandlerFunc 实现的
1 | package main |
访问http://localhost:8080/test
将返回Hello, you've hit /test
如何实现的?
http.HandleFunc 的底层实现会将你传递的函数(如 myHandler)转为一个匿名的结构体,并为这个结构体实现 ServeHTTP 方法。这个匿名结构体的 ServeHTTP 方法就是你提供的 myHandler 函数。可以理解为 http.HandleFunc 自动为你完成了接口的实现。
HTTP 请求对象 (http.Request)
http.Request 是 Go 中处理 HTTP 请求的核心结构体,包含了许多关于请求的详细信息,包括请求方法、URL、头部、请求体等。通过这个结构体,你可以访问并处理各种与 HTTP 请求相关的数据,进而实现 HTTP 服务的功能。
在本地显示读取控制。
http.Request
的主要字段(仅举例两个)
Method
(请求方法)- 类型:string
- 描述:表示 HTTP 请求的类型,如 GET、POST、PUT、DELETE 等。
- 例如,如果是一个 GET 请求,Method 会是 “GET”,如果是一个 POST 请求,Method 会是 “POST”。
- 例子:r.Method 可以帮助你判断请求的类型。
URL
(请求的URL)- 类型:*url.URL
- 描述:表示客户端请求的 URL 地址。这个字段是一个指向 url.URL 结构体的指针,包含了完整的 URL 信息。
- 通过 r.URL.Path,你可以获取请求的路径(例如 /hello)。而 r.URL.Query() 可以用于获取 URL 查询参数(如 ?name=John)。
- 例子:
- r.URL.Path:/hello 代表访问路径。
- r.URL.RawQuery:查询字符串部分,例如 name=John&age=30。
HTTP 响应对象 (http.ResponseWriter)
示例代码
1 | package main |
设置响应头
代码:
1 | w.Header().Set("Content-Type", "text/plain") |
作用
- 响应头(HTTP Headers)是服务器向客户端提供的关于响应的元信息。
- Content-Type 是一个常用的响应头,它告诉客户端响应体的内容类型和格式,帮助客户端正确解析和处理数据。
告知客户端数据类型:
客户端需要知道返回的数据是什么类型,以便正确解析。例如:- text/plain:表示纯文本。
- text/html:表示 HTML 文档。
- application/json:表示 JSON 数据。
如果没有正确设置,客户端可能会错误地解析或显示数据。
支持不同的客户端
- 浏览器、移动设备、API 客户端等都依赖 Content-Type 来决定如何处理服务器返回的数据。
- 例如,Content-Type: text/html 会让浏览器将响应当作网页渲染,而 Content-Type: application/json 会让 API 客户端将其解析为 JSON 对象。
设置响应状态码
代码:
1 | w.WriteHeader(http.StatusCreated) |
作用
状态码的作用是面向客户端的
客户端通过状态码判断请求结果
- 状态码如 200 OK 表示请求成功。
- 状态码如 404 Not Found 表示客户端请求的资源不存在。
- 状态码如 500 Internal Server Error 表示服务器内部出了问题。
客户端行为会依赖状态码
- 浏览器看到 301 Moved Permanently 会自动重定向到新的 URL。
- API 客户端根据 401 Unauthorized 提示用户需要登录。
- 搜索引擎看到 503 Service Unavailable 会知道服务器暂时不可用,稍后再尝试抓取页面。
HTTP客户端
HTTP 客户端主要用于发送 HTTP 请求到指定的服务器,并接收服务器的响应。net/http 提供了一些简单易用的函数和类型,例如 http.Get、http.Post、http.Client 等。
核心类型&函数
(1) http.Client
http.Client 是一个可配置的 HTTP 客户端,用于发送请求和接收响应。
默认客户端是 http.DefaultClient。
(2) http.Request
表示一个 HTTP 请求,包含请求方法、URL、头部、请求体等。
(3) http.Response
表示一个 HTTP 响应,包含状态码、头部、响应体等。
(4) 快捷方法
- http.Get:发送简单的 GET 请求。
- http.Post:发送简单的 POST 请求。
- http.Head、http.PostForm 等:发送其他类型的请求。
懒得写例子直接解释gobyexample里的
1 | package main |
HTTP服务端
HTTP 服务端用于处理客户端的 HTTP 请求并返回响应。Go 提供了一个高效的 HTTP 服务器实现,支持路由处理和并发。
核心类型&函数
(1) http.Handler
接口,表示 HTTP 请求的处理器。
需要实现 ServeHTTP(w http.ResponseWriter, r *http.Request) 方法。
(2) http.Server
表示一个 HTTP 服务器,包含监听地址、处理器和其他配置。
默认服务器是通过 http.ListenAndServe 启动的。
(3) http.ServeMux
默认的路由器,负责将请求分发给对应的 Handler。
1 | package main |