# 多路复用器

也就是 ServeMux,它的作用就是实现 url 与处理器 handler 的映射(这里虽然说是处理器,但是实际上就是处理函数)

golang 中的实现:

type ServeMux struct {
	mu    sync.RWMutex
	m     map[string]muxEntry
	es    []muxEntry // slice of entries sorted from longest to shortest.
	hosts bool       // whether any patterns contain hostnames
}

我们使用 http 库写一个简单的 serve 端:

package main
import (
	"io"
	"log"
	"net/http"
)
func main() {
	http.HandleFunc("/test", 
		func(rw http.ResponseWriter, r *http.Request) {
			io.WriteString(rw, "hello world!")
		})
	err := http.ListenAndServe("0.0.0.0:33787", nil)
	if err != nil{
		log.Fatal(err)
	}
}

直接调用了 http.handlerFunchttp 库会使用系统默认的 ServerMux ,因此,在 err := http.ListenAndServe("0.0.0.0:33787", nil) 中第二个传入的参数就是 nil。

因为这个 defaultServerMux 是一个全局变量,也就是说,第三方代码也可以调用 http 库,然后修改这个 defaultServerMux 。所以我们需要自己定制一个多路复用器。

sm := http.NewServeMux()
	sm.HandleFunc("/test", 
		func(rw http.ResponseWriter, r *http.Request) {
			io.WriteString(rw, "hello world!")
		})
	err := http.ListenAndServe("0.0.0.0:33787", sm)

代码很简单,就是 new 一个 ServerMux 。然后传给 listen

# 静态文件访问

可以直接调用 GIN:

e := gin.Default()
	e.Static("/files/", "./")
	e.Run(":33787")
	e.GET("/",func(c *gin.Context) {c.String(http.StatusOK,"hello world!")})

访问 myip:33787/files/C.html ,显示:

image-20220121103906562

直接就可以把 html 文件给显示出来。

# 请求头

请求头格式 type Header map[string]string

可以看到请求头就是一个 string map,它会记录 request 的头信息,一般对于 request 都是取出 header 里信息的。

这里有关于请求头的各个参数信息: HTTP 请求头

查询请求头参数:

func Header(w http.ResponseWriter, r *http.Request)  {
	s := r.Header.Get("Accept")
	fmt.Printf("r.Header: %v\n", r.Header)
	fmt.Printf("s: %v\n", s)
	fmt.Println("hello world")
	w.Write([]byte(s))
}
func main() {
	http.HandleFunc("/header", Header)
	err := http.ListenAndServe(":33787", nil)
	if err != nil {
		fmt.Println(err)
	}
}

比如查 Accept ,表示当前浏览器可以接受的文件类型,假设这里有 image/webp,表示当前浏览器可以支持 webp 格式的图片,那么当服务器给当前浏览器下发 webp 的图片时,可以更省流量。

# 请求体

就是 postman 发 get 或 post 携带的键值对,如果是 get 请求,那么 body 会内嵌在 url 里,如果是 post 请求就发送表单,这样发送密码时用 post 就安全。

http 包: req.body.read([]byte)

gin : c.Param(string) 就能查键值对。

这个请求体比请求头常用。

e := gin.Default()
e.GET("/",func(c *gin.Context) {c.Param("name")})

# 响应头

这里有一篇文章列出了响应头参数:响应头参数

WriteHeader :设置状态码

Header().set() : 设置其他参数,注意要在 writeHeader 之前进行设置。

重定向:

func Header(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Location", "https://www.google.com")
	w.WriteHeader(301)
}
func main() {
	http.HandleFunc("/header", Header)
	http.ListenAndServe("0.0.0.0:33787",nil)
}
更新于

请我喝[茶]~( ̄▽ ̄)~*

Kalice 微信支付

微信支付

Kalice 支付宝

支付宝