在讲述GoWeb之前,我们先简单看下Web应用相关的知识。
注1:客户端端指的是浏览器。那么,作为后端程序员,我们的工作主要在服务器端,与客户端的交互和数据库的交互。
注2:在TCP应用中,程序员一般同时编写客户端和服务器端,工作量比较大。但在Web开发中,程序员把主要经历花在客户端。
注3:服务器端处理客户端请求的一般过程。服务器端在某个指定的端口监听(例如:9090 端口与具体的某个程序相对应,可以理解为值一扇们)。当服务器端接收客户端的请求时,先会交给多路复用器解析URL和找到匹配的处理器处理请求。(其实客户端和服务器端的交互与服务器端和数据库的交互一样,只是,在与数据库端交互式,数据库充当服务器的角色)
注4:我们一般需要提供IP和端口,通过IP可以找到主机,通过端口找到主机上的程序
http协议(超文本传输协议)
进行Web开发,必不可少的需要了解http协议。
在这里我们先说下,数据这么在服务器端和客户端进行传输的。我们知道最终都要通过物理线路进行的。也就是我们说的协议栈,一层层的解包封包。那么,我们就很容易理解到,数据是通过字节序列的方式进行传输的,在TCP中,我们有时需要定义自己的消息模型,通过序列化将结构体类型的数据转换成字节序列,进行序列传输。在Web的底层其实也是socket编程,是不过我们不需要去考虑那么多,应为有人帮我们做好了,我们一般只需要应用相应的API就行。
http协议:其实就是一种规范,一种在客户端与服务器端的之间的通信规则。(消息模型)
http协议中的相关规定:
1.客户端与服务器端之间传送的内容称为报文
2.客户端发送给服务器的报文叫做:请求报文
服务器端送个客户端的报文叫做:响应报文
http协议的会话方式
注1:浏览器与web服务器之间的连接是短暂的,每次连接只处理一个连接和响应。对每一个页面的访问,浏览器和服务器之间都要建立一次连接。
注2:浏览器与web服务器端之间的所有通讯都是完全独立分开的请求和响应对(每一协程可以处理一个请求和响应)
报文
报文格式:
报文首部:请求或响应的属性或内容
空行(一个回车加一个换行)
报文主体:被发送的数据
请求报文:
那么我们怎么能看到这些信息的,在浏览器中按F12就可以看到
GET请求与POST请求的区别:(POST请求需要服务器的支持)
1.GET请求没有请求体
2.GET请求比POST请求快大概两倍作用
3.GET请求具有缓存,POST请求没有缓存(所以GET请求更快)
4.GET请求时的参数会跟在浏览器地址栏的后面 POST请求在表单中(因为GET请求没有请求体)
5.GET请求不安全(应为参数可见)
6.GET请求的数据传输长度有限制,POST基本没有什么限制
常见响应状态码
1XX :提示信息,表示信息已被成功接收,继续处理
2XX: 表示请求已被接收、理解、处理(200)
3XX: 重定向,完成请求需要进一步处理(302)
4XX: 客户端错误(404请求资源不存在)
5XX: 服务器端错误(500)
GO创建web服务器
go提供了一系列用于创建web服务器的标准,而非常简单。只需要调用net/http包中的ListenAndServe函数并传入网络地址和负责处理的处理器就ok了。
注1:如果网络地址为空,则默认使用hhtp的端口80进行网络连接。如果处理器参数为nil,则使用默认的多路复用转发器DefaultServeMux(Default默认 Serve服务器 Mux多路复用器)。
多路复用器接收到用户的请求之后根据请求的URL来判断使用哪个处理器处理请求,然后就会重定向到对应的处理器处理请求。
创建处理器(2两种)
1.type HandlerFunc func(ResponseWriter,*Request)
==>参数必须要是这两个,处理器有一个接口Handler(go中接口的实现方法来实现接口的)
==>通过实现Handler接口创建自己的处理器
==>HandlerFunc函数会帮我们创建一个Handler,b并调用
package main import ( "fmt" "net/http" ) //创建处理函数 func MyHandlerFunc(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "aaaa") //向文件w写入aaaa } func main() { //通过URL找到处理器 第一个参数就是URL http.HandleFunc("/", MyHandlerFunc) //在localhost:9090端口监听,使用DefaluteServeMux http.ListenAndServe(":9090", nil) }
2.创建自己的Handler
package main import ( "fmt" "net/http" ) //声明一个结构体 type MyHandler struct{} //给MyHandler绑定Handler接口ServeHTTP(....)方法 func (this *MyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { fmt.Fprintln(w, "我是MyHandler") } func main() { //创建一个MyHandler实例 myHandler := MyHandler{} //处理请求 http.Handle("/", &myHandler) http.ListenAndServe(":9090", nil) }
创建多路复用器
GO提供了NewServerMux的方法,让我们自己创建一个多路复用器
func NewServeMux() *ServeMux
package main import ( "fmt" "net/http" ) func sayHello(w http.ResponseWriter, r *http.Request) { fmt.Fprintln(w, "Hello golang") } func main() { myMux := http.NewServeMux() myMux.HandleFunc("/", sayHello) http.ListenAndServe(":9090", myMux) }
创建服务器
GO提供共Server结构体,我们可以创建一个Server的实例,去配置Server中的一些配置。
package main import ( "fmt" "net/http" ) type MyHandler2 struct{} func (this *MyHandler2) ServeHTTP(w http.ResponseWriter, r *http.Request) { fmt.Fprintln(w, "小王子") } func main() { myHandler := MyHandler2{} //注:这里没有HanlderFunc函数可以调用了,要在定义server时指定 server := http.Server{ Addr: ":9090", Handler: &myHandler, } server.ListenAndServe() }