http协议
HTTP协议没有状态,即同一个客户端两次请求没有对应关系,为了解决这个问题引入session和cookie的概念
http请求由请求行(Request Line)和请求头部(Header)、空行和请求数据等4个部分组成。
请求行:方法 URL 版本 cr lf(\r\n)
请求头部:
字段名 字段值 cr lf字段名 字段值 cr lf
…
空行:cr lf
请求数据(请求体):(其他数据)
服务器接收到请求之后会做出响应,也是四部分组成:状态行、响应头、空行、响应体
状态行:协议版本号 状态码 cr lf
响应头:(客户端可以使用的一些信息如Date(生成响应的日期)、Content-Type(MIME类型及编码格式)和Connection(默认是长连接)等等)
字段名 字段值 cr lf字段名 字段值 cr lf
…
空行:cr lf
响应体:(响应正文)
不同状态码对应信息:
- 1XX:接收的请求正在处理
- 2XX:请求正常处理完毕
- 3XX:需要进行附加操作以完成请求
- 4XX:服务器无法处理请求
- 5XX:服务器处理请求出错
访问web站点的过程
- 输入url之后,浏览器先访问DNS服务器获取需访问服务器的真实ip
- 找到真实ip对应的服务器,建立tcp连接
- 浏览器发送HTTP Request
- 服务器接受到HTTP Request之后响应HTTP Response给浏览器
- 浏览器接收完HTTP Response之后断开tcp连接
使用Go语言构建服务器
【实例】
1 | package main |
接收和处理请求
Web工作中的几个概念
net/http标准库中由客户端和服务端两个部分
- 服务端:Server,ServerMux,Handler/HandlerFunc,Header,Request,Cookie
- 客户端:Client,Response,Header,Request,Cookie
Conn:表示用户每次请求链接
http包服务端执行流程:
- 创建Listen Socket,监听指定的端口,等待客户端的请求
- Listen Socket接收到请求,得到Client Socket,通过Client Socket与客户端通信
- 服务端处理请求:从Client Socket中读取请求体,交给Handler处理,将响应体通过Client Socket写给客户端
处理器处理请求
流程:
- ListenAndServe进行监听:net.Listen(“tcp”,addr)
- 接收请求并创建连接Conn:srv.Serve(l net.Listener):进入循环{rw := Accept();c := srv.NewConn();go c.serve()}
- 处理链接conn.serve():分析请求,映射url
解析请求体
具体可见”使用Go语言构建服务器”中的【实例】
返回响应体
主要通过接口ResponseWriter接口中的方法:
1 | type ResponseWriter interface{ |
实践案例:Golang Web 框架 Gin 实践
go get -u github.com/gin-gonic/gin
直接引入:
1 | import( |
1 | package main |
常用Restful方法有:GET,PUT,POST,DELETE等
路由的一些使用技巧和方式:
比如:由中携带参数
1 | router.GET("/user/:name",func(c *gin.Context){ |
如上可以使用c.Param(s)(”name”)方法读取参数的值,但是gin不支持路由正则表达式,只有像 /user/Extious
这个结构的路由才可以被匹配,而 /user
,/user/
,/user/Extious/
都不会被匹配。
gin还提供了”*”处理参数:
router.GET("/user/:name/*action",func)
这个时候处理器可以匹配到 /user/Extious/
,/user/Extious/Send
,/user/Extious
注意:路由参数是指API参数和URL参数不同,URL参数是路由之后
/api?name="Extious"
里边name这种,需要用到Query()等方法遍历到
中间件的意思是对一组接口的统一操作,常用于:记录log,错误handler,对部分接口的鉴权
1 | package main |
服务端数据存储
MySQL采用gorm的一系列接口