golang标准库http
http协议
- http:超文本传输协议Hyper Text Transfer Protocol。
- http属于应用层协议,它在传输层用的是tcp协议。
- 无状态,对事务处理没有记忆能力(对比TCP协议里的确认号)。如果要保存状态需要引用其他技术,如cookie。
- 无连接,每次连接只处理一个请求。早期带宽和计算资源有限,这么做是为了追求传输速度快,后来通过Connection: Keep-Alive实现长连接。http1.1废弃了Keep-Alive,默认支持长连接。

请求方法
请求方法 | 解释 |
---|---|
GET | 请求获取Request-URI所标识的资源 |
POST | 向URI提交数据(例如提交表单或上传数据) |
HEAD | 类似于GET,返回的响应中没有具体的内容,用于获取报头 |
PUT | 对服务器上已存在的资源进行更新 |
DELETE | 请求服务器删除指定的页面 |
CONNECT | HTTP/1.1预留,能够将连接改为管道方式的代理服务器 |
OPTIONS | 查看服务端性能 |
TRACE | 回显服务器收到的请求,主要用于测试或诊断 |
PATCH | 同PUT,可只对资源的一部分更新,资源不存在时会创建 |
GET、POST和HEAD是http1.0就有的,后面的请求方法是http1.1新增的。客户端发起一个请求时,这个请求可能要穿过防火墙、代理、网关或其他一些应用程序。每个中间节点都可能会修改原始的HTTP请求。TRACE 方法允许客户端在 最终将请求发送给服务器时,看看它变成了什么样子。TRACE请求会在目的服务器端发起一个环回诊断。行程最后一站的服务器会弹回一条TRACE响应,并在响应主体中携带它收到的原始请求报文。这样客户端就可以查看在所有中间HTTP应用程序组成的请求/响应链上,原始报文是否,以及如何被毁坏或修改过。CONNECT方法是HTTP/1.1协议预留的,能够将连接改为管道方式的代理服务器。通常用于SSL加密服务器的链接与非加密的HTTP代理服务器的通信。OPTIONS方法请求Web服务器告知其支持的各种功能。通过使用OPTIONS,客户端可以在与服务器进行交互之前,确定服务器的能力,这样它就可以更方便地与具备不同特性的代理和服务器进行互操作了。
实际中server对各种request method的处理方式可能不是按协义标准来的,比如server收到PUT请求时偏偏执行DELETE操作,同理仅用一个GET方法也能实现增删改查的全部功能。大多数浏览器只支持GET和POST。
URL
- URI:uniform resource identifier,统一资源标识符,用来唯一的标识一个资源。
- URL: uniform resource locator,统一资源定位器,它是一种具体的URI,指明了如何locate这个资源。
- URL举例:

协议版本
现在广泛应用的协议版本是HTTP/1.1。
请求头
Header | 解释 | 示例 |
---|---|---|
Accept | 指定客户端能够接收的内容类型 | Accept: text/plain, text/html |
Accept-Charset | 浏览器可以接受的字符编码集 | Accept-Charset: iso-8859-5 |
Accept-Encoding | 指定浏览器可以支持的web服务器返回内容压缩编码类型 | Accept-Encoding: compress, gzip |
Accept-Language | 浏览器可接受的语言 | Accept-Language: en,zh |
Authorization | HTTP授权的授权证书 | Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ== |
Cache-Control | 指定请求和响应遵循的缓存机制 | Cache-Control: no-cache |
Connection | 表示是否需要持久连接(HTTP 1.1默认进行持久连接) | Connection: close |
Cookie | HTTP请求发送时,会把保存在该请求域名下的所有cookie值一起发送给web服务器 | Cookie: $Version=1; Skin=new; |
Content-Length | 请求的内容长度 | Content-Length: 348 |
Content-Type | 指定正文(body)的数据格式 | Content-Type: application/x-www-form-urlencoded |
User-Agent | 浏览器信息 | Mozilla/5.0 (Windows NT 6.1; Win64; x64) |
Content-Type
- application/x-www-form-urlencoded
- 浏览器的原生form表单,如果不设置 Content-Type 属性,则默认以 application/x-www-form-urlencoded 方式传输数据
- 正文例如:name=manu&message=this_is_great
- multipart/form-data
- 上传文件时使用multipart/form-data,支持多种文件格式
- 正文例如: name="text"name=“file”; filename="chrome.png"Content-Type: image/png… content of chrome.png
- application/json
- 正文例如:{“title”:“test”,“sub”:[1,2,3]}
- text/xml
- 正文例如:
examples.getStateName
- 正文例如:
请求正文
GET请求没有请求正文。POST即可以把一部分参数放在url里,也可以把一部分参数放在请求正文里,如下是一个完整的POST请求
1 | POST /post?id=1234&page=1 HTTP/1.1 |
GET和POST的区别:
- get的请求参数全部在url里,参数变时url就变;post可以把参数放到请求正文里,参数变时url不变。
- 虽然http协议并没有对url和请求正文做长度限制,但在实际中浏览器对url的长度限制比请求正文要小很多,所以post可以提交的数据比get要大得多。
- get比post更容易受到攻击(源于get的参数直接暴露在url里)。
http response

响应状态及话术
code | phrase | 说明 |
---|---|---|
200 | Ok | 请求成功 |
400 | Bad Request | 客户端有语法错误,服务端不理解 |
401 | Unauthorized | 请求未经授权 |
403 | Forbidden | 服务端拒绝提供服务 |
404 | Not Found | 请求资源不存在 |
500 | Internal Server Error | 服务器发生不可预期的错误 |
503 | Server Unavailable | 服务器当前有问题,过段时间可能恢复 |
响应头
Header | 解释 | 示例 |
---|---|---|
Allow | 对某网络资源的有效的请求行为 | Allow: GET, HEAD |
Date | 原始服务器消息发出的时间 | Date: Tue, 15 Nov 2010 08:12:31 GMT |
Content-Encoding | 服务器支持的返回内容压缩编码类型 | Content-Encoding: gzip |
Content-Language | 响应体的语言 | Content-Language: en,zh |
Content-Length | 响应体的长度 | Content-Length: 348 |
Cache-Control | 指定请求和响应遵循的缓存机制 | Cache-Control: no-cache |
Content-Type | 返回内容的MIME类型 | Content-Type: text/html; charset=utf-8 |
响应正文可以是html、json、xml、普通文本,等等。
完整http response举例:
1 | HTTP/1.1 200 OK |
https

HTTP + 加密 + 认证 + 完整性保护 = HTTPS(HTTP Secure)
go语言http标准库
http_server.go
1 | package main |
运行结果:
request method: POST
request host: 127.0.0.1:5656
request url: /
request proto: HTTP/1.1
request header Accept-Encoding: [gzip]
request header User-Agent: [Go-http-client/1.1]
request header Content-Length: [12]
request header Content-Type: [text/plain]
request body:: Hello Server
http_client.go
1 | func simpleGet() { |
运行结果:
response proto: HTTP/1.1
response status: 200 OK
response header
Date: [Fri, 13 Jan 2023 14:21:03 GMT]
Content-Length: [9]
Content-Type: [text/plain; charset=utf-8]
response body: Hello Boy
路由插件
- 安装 go get -u github.com/julienschmidt/httprouter
- Router实现了http.Handler接口。
- 为各种request method提供了便捷的路由方式。
- 支持restful请求方式。
- 支持ServeFiles访问静态文件。
- 可以自定义捕获panic的方法。
1 | package main |
结合gin路由
1 | package main |
请求校验
首先安装go get github.com/go-playground/validator
范围约束
- 对于字符串、切片、数组和map,约束其长度。len=10, min=6, max=10, gt=10。
- 对于数值,约束其取值。min, max, eq, ne, gt, gte, lt, lte, oneof=6 8。
跨字段约束
- 跨字段就在范围约束的基础上加field后缀。
- 如果还跨结构体(cross struct)就在跨字段的基础上在field前面加cs:范围约束 cs field。
字符串约束
- contains包含子串。
- containsany包含任意unicode字符, containsany=abcd。
- containsrune包含rune字符, containsrune= ☻。
- excludes不包含子串。
- excludesall不包含任意的unicode字符,excludesall=abcd。
- excludesrune不包含rune字符,excludesrune=☻。
- startswith以子串为前缀。
- endswith以子串为后缀。
唯一性uniq
- 对于数组和切片,约束没有重复的元素。
- 对于map,约束没的重复的value。
- 对于元素类型为结构体的切片,unique约束结构体对象的某个字段不重复,通过unqiue=field指定这个字段名。
Friends []Uservalidate:"unique=Name"
1 | package main |
运行结果:
field PassWord 不满足条件 min
field PassRepeat 不满足条件 eqfield
field Email 不满足条件 email
param error: validator: (nil int)
==============
field PassWord 不满足条件 eqcsfield
field PassRepeat 不满足条件 eqfield
field Email 不满足条件 email
http中间件
中间件的作用:将业务代码和非业务代码解耦。非业务代码指限流、超时控制、打日志等等。
中间件的实现原理:传入一个http.Handler,外面套上一些非业务功能代码,再返回一个http.Handler。支持中间件层层嵌套。通过HandlerFunc把一个func(rw http.ResponseWriter, r *http.Request)函数转为Handler。
1 | package main |
GIN
Gin是一款高性能的、简单轻巧的http Web框架。安装方式go get -u github.com/gin-gonic/gin。
路由
Gin的路由是基于httprouter做的,支持GET、POST、PUT、PATCH、DELETE、OPTIONS、HEAD。支持路由分组,不用重复写上级路径。
1 | package main |
参数获取
- c.Query() 从GET请求的URL中获取参数。
- c.Param()从Restful风格的url中获取参数。
- c.PostForm() 从post表单中获取参数。
- c.FormFile() 获取上传的文件,消息类型为form-data。
- c. MultipartForm() multipart/form-data可以上传多个form-data 并且用分隔符进行分割。
1 | package main |
利用postman提交http请求
提交普通post请求
上传文件
提交json
提交xml
提交yaml
生成response
- c.String() response Content-Type=text/plain。
- c.JSON() response Content-Type= application/json。
- c.XML() response Content-Type= application/xml。
- c.HTML() 前端写好模板,后端往里面填值。
- c.Redirect() 重定向。
1 | package main |
参数检验
GIN的参数检验是基于go-playground/validator实现的。
1 | package main |
运行结果:
{“Name”:“zcy”,“Score”:1,“Enrollment”:“2021-08-23T00:00:00+08:00”,“Graduation”:“2021-09-23T00:00:00+08:00”}
中间件
1 | package main |
gin-gonic/contrib上提供了丰富的第三方中间件。
会话
http是无状态的,即服务端不知道两次请求是否来自于同一个客户端。Cookie由服务端生成,发送给客户端,客户端保存在本地。客户端每次发起请求时把Cookie带上,以证明自己的身份。HTTP请求中的Cookie头只会包含name和value信息(服务端只能取到name和value),domain、path、expires等cookie属性是由浏览器使用的,对服务器来说没有意义。Cookie可以被浏览器禁用。
server_session.go
1 | package main |
client_session.go
1 | func main() { |
Beego
beego是一个大而全的http框架,用于快速开发go应用程序。bee工具提供诸多命令,帮助我们进行 beego 项目的创建、热编译、开发、测试、和部署。
1 | go get github.com/astaxie/beego |
beego的八大模块互相独立,高度解耦,开发者可任意选取:
- 日志模块
- ORM模块
- Context模块。封装了request和response
- Cache模块。封装了memcache、redis、ssdb
- Config模块。解析.ini、.yaml、.xml、.json、.env等配置文件
- httplib模块
- Session模块。session保存在服务端,用于标识客户身份,跟踪会话
- toolbox模块。健康检查、性能调试、访问统计、计划任务
MVC开发模式

在Model层可以使用beego提供的ORM功能。
client
1 | package main |
模板
1 | package main |
1 | package main |