http web 开发
1.http请求包
Accept-Encoding:gzip, deflate, br 是否支持流压缩
Accept-Language:zh-CN,zh;q=0.9 浏览器申明自己接收的编码方法
Cache-Control:max-age=0
Connection:keep-alive 当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,如果客户端再次访问这个服务器上的网页,会继续使用这一条已经建立的连接
Cookie:hibext_instdsigdip=1; hibext_instdsigdipv2=1; _ga=GA1.1.3997200.1517318632; csrftoken=M897uTeIq8mg2TjkJp1fmnifvhHNKoe5SvW50bCbrQVbxNq5PILmvl7UEoFhC5AZ; OUTFOX_SEARCH_USER_ID_NCOO=109431709.18546157; sessionid=903plvwdj8j8a4qf10vammytmkgtkarm; _gid=GA1.1.538902467.1519714828; _gat=1; trdipcktrffcext=1
Host:127.0.0.1:8080 请求的主机
Upgrade-Insecure-Requests:1
User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36 客户端(浏览器)相关信息
Request Method:GET
进一步分解如下图:

2.响应报文解析:
HTTP的响应报文也由三部分组成(响应行+响应头+响应体):


①报文协议及版本; 
②状态码及状态描述; 
③响应报文头,也是由多个属性组成; 
④响应报文体,即我们真正要的“干货”。
1.简单http客户端
package main
import (
	"fmt"
	"io/ioutil"
	"net/http"
)
func main(){
	res,err := http.Get("https://www.baidu.com")
	if err != nil {
		fmt.Println("Get err:",err)
		return
	}
	data,err := ioutil.ReadAll(res.Body)
	if err != nil {
		fmt.Println("read failed:",err)
		return
	}
	fmt.Println(string(data))
}
运行结果:
<html>
<head>
        <script>
                location.replace(location.href.replace("https://","http://"));
        </script>
</head>
<body>
        <noscript><meta http-equiv="refresh" content="0;url=http://www.baidu.com/"></noscript>
</body>
</html>
2.http服务端
package main
import(
	"fmt"
	"net/http"
)
func hello(w http.ResponseWriter,r *http.Request){
	fmt.Fprintf(w,"helloworld")
}
func main(){
	http.HandleFunc("/",hello)
	err:=http.ListenAndServe(":8080",nil)
	if err != nil {
		fmt.Println("http listen failed err:",err)
	}
}
访问:

3.用客户访问自己的httpserver
package main
import (
	"fmt"
	"io/ioutil"
	"net/http"
)
func main(){
	res,err := http.Get("http://127.0.0.1:8080")
	if err != nil {
		fmt.Println("Get err:",err)
		return
	}
	data,err := ioutil.ReadAll(res.Body)
	if err != nil {
		fmt.Println("read failed:",err)
		return
	}
	fmt.Println(string(data))
}
访问结果:

4.http常见请求方法
Get Post Put Delete Head
5.head 请求实例:
package main
import (
	"net/http"
	"fmt"
	"io/ioutil"
	// "strings"
)
func test3(){
	var url = []string{
		"http://www.baidu.com",
		"http://www.google.com/",
		"http://taobao.com",
	}
	for _,v := range url{
		reps,err:= http.Head(v)
		if err != nil {
			fmt.Println("Head failed",err)
			continue
		}
		fmt.Println("head sucess:",reps)
	}
}
func main(){
	test3()
}
运行结果如下:
  
6.http常见状态码
http.StatusContinue = 100
http.StatusOK = 200
http.StatusFound = 302
http.StatusBadRequest = 400
http.StatusUnauthorized =
401
http.StatusForbidden = 403
http.StatusNotFound = 404
http.StatusInternalServerEr
ror = 500 
7.表单处理
package main
import (
	"fmt"
	"io"
	"net/http"
)
const form =`<html><body><form action="#" method="post" name="bar">
<input type="text" name="user"/>
<input type="text" name="pwd"/>
<input type="submit" value="Submit"/>
</form></body><html>`
func SimpleServer(w http.ResponseWriter, r *http.Request){
	io.WriteString(w,"<h1>hello,world</h1>")
}
func FormServer(w http.ResponseWriter, r *http.Request){
	w.Header().Set("Content-Type","text/html")  //设置响应头内容
	w.Header().Set("wang","haijun")
	
	switch r.Method{
	case "GET":
		io.WriteString(w,form)   //如果是Get请求,则把form表单内容返回去
	case "POST":
		r.ParseForm()           //解析表单,获取表单内容
		io.WriteString(w,r.Form["user"][0])		 //获取表单内容,并返回给浏览器
		io.WriteString(w,r.FormValue("user"))   //获取表单内容,并返回给浏览器
		io.WriteString(w,"\n")
		io.WriteString(w,r.Form["pwd"][0])
		io.WriteString(w,r.FormValue("pwd"))
	}
}
func main(){
	http.HandleFunc("/test1", SimpleServer)
	http.HandleFunc("/test2", FormServer)
	err :=http.ListenAndServe("0.0.0.0:80",nil)
	if err != nil {
		fmt.Println(err)
	}
}
  
8.http panic处理
package main
import (
	"fmt"
	"io"
	"net/http"
)
const form =`<html><body><form action="#" method="post" name="bar">
<input type="text" name="user"/>
<input type="text" name="pwd"/>
<input type="submit" value="Submit"/>
</form></body><html>`
func SimpleServer(w http.ResponseWriter, r *http.Request){
	var p *int   //制造错误
	*p = 100
	io.WriteString(w,"<h1>hello,world</h1>")
}
func FormServer(w http.ResponseWriter, r *http.Request){
	w.Header().Set("Content-Type","text/html")  //设置响应头内容
	w.Header().Set("wang","haijun")
	
	switch r.Method{
	case "GET":
		io.WriteString(w,form)   //如果是Get请求,则把form表单内容返回去
	case "POST":
		r.ParseForm()           //解析表单,获取表单内容
		io.WriteString(w,r.Form["user"][0])		 //获取表单内容,并返回给浏览器
		io.WriteString(w,r.FormValue("user"))   //获取表单内容,并返回给浏览器
		io.WriteString(w,"\n")
		io.WriteString(w,r.Form["pwd"][0])
		io.WriteString(w,r.FormValue("pwd"))
	}
}
func main(){
	http.HandleFunc("/test1",SimpleServer)
	http.HandleFunc("/test2", FormServer)
	err :=http.ListenAndServe("0.0.0.0:80",nil)
	if err != nil {
		fmt.Println(err)
	}
}
上面人为制造了一个错误,但是并没有捕捉,现在go语言已经经过 了处理,服务器不会崩溃,原来如果不捕捉就会崩溃,不过最好是捕捉一下。看没有捕捉的运行结果:
运行服务:
go run .\main.go
访问url:127.0.0.1/test1

看服务器报错:

继续访问url:127.0.0.1/test2
 
test2还可以访问,go内部经过了处理。
自己捕捉错误:
package main
import (
	"fmt"
	"io"
	"net/http"
)
const form =`<html><body><form action="#" method="post" name="bar">
<input type="text" name="user"/>
<input type="text" name="pwd"/>
<input type="submit" value="Submit"/>
</form></body><html>`
func SimpleServer(w http.ResponseWriter, r *http.Request){
	var p *int   //制造错误
	*p = 100
	io.WriteString(w,"<h1>hello,world</h1>")
}
func FormServer(w http.ResponseWriter, r *http.Request){
	w.Header().Set("Content-Type","text/html")  //设置响应头内容
	w.Header().Set("wang","haijun")
	
	switch r.Method{
	case "GET":
		io.WriteString(w,form)   //如果是Get请求,则把form表单内容返回去
	case "POST":
		r.ParseForm()           //解析表单,获取表单内容
		io.WriteString(w,r.Form["user"][0])		 //获取表单内容,并返回给浏览器
		io.WriteString(w,r.FormValue("user"))   //获取表单内容,并返回给浏览器
		io.WriteString(w,"\n")
		io.WriteString(w,r.Form["pwd"][0])
		io.WriteString(w,r.FormValue("pwd"))
	}
}
func main(){
	http.HandleFunc("/test1",logPanics(SimpleServer))
	http.HandleFunc("/test2", FormServer)
	err :=http.ListenAndServe("0.0.0.0:80",nil)
	if err != nil {
		fmt.Println(err)
	}
}
func logPanics(handle http.HandlerFunc) http.HandlerFunc{   //接收一个http.HandlerFunc类型的参数,并返回一个http.HandlerFunc类型的函数
	return func(writer http.ResponseWriter,r *http.Request){
		defer func(){
			if x:=recover(); x!= nil{
				fmt.Printf("%v caught panic%v",r.RemoteAddr,x)
			}
		}()
		handle(writer,r)                                  //相当于调用 SimpleServer函数,通过logPanics这个函数,即完成原来函数的功能,又增加了新的功能
	}
}
访问url:127.0.0.1/test1

页面没有报错,后台有错误,可以定向到日志中:

                    
                
                
            
        
浙公网安备 33010602011771号