状态码 | http方法 | 描述 |
---|---|---|
100 | http.StatusContinue = 100 | 一般文件上传的时候使用 |
200 | http.StatusOK = 200 | 服务器状态正常 |
302 | http.StatusFound = 302 | 跳转 |
400 | http.StatusBadRequest = 400 | 非法请求构造协议包无法解析,服务器无法解析处理 |
401 | http.StatusUnauthorized = 401 | 权限未通过 |
403 | http.StatusForbidden = 403 | 不让访问该资源 |
404 | http.StatusNotFound = 404 | 页面不存在,资源未找到 |
500 | http.StatusInternalServerError = 500 | 服务器内部错误,无法处理请求, |
502 | php | nginx请求php, php无响应nginx 返回502 |
package main
import (
"fmt"
"net/http"
)
func hello(w http.ResponseWriter, r *http.Request) {
fmt.Println("index hello")
fmt.Fprintf(w, "index hello
")
}
func login(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "user login")
}
func main() {
http.HandleFunc("/", hello)
http.HandleFunc("/user/login", login)
err := http.ListenAndServe("0.0.0.0:8000", nil)
if err != nil {
fmt.Println("server failed, err:", err)
}
}
编译并运行
$ go build go_dev/day10/example/http_server
$ sudo ./http_server
打开浏览器验证路径/
, /user/login
http.Get 来获取一个url的request的对象,request.BoBy 是网页信息(html)
package main
import (
"fmt"
"io/ioutil"
"net/http"
)
func main() {
res, err := http.Get("http://localhost:8000")
if err != nil {
fmt.Println("get err:", err)
return
}
data, err := ioutil.ReadAll(res.Body)
if err != nil {
fmt.Println("read data err:", err)
return
}
fmt.Printf("data: %s", string(data))
fmt.Printf("data: %v\n", data)
}
运行:
%v是打印原始信息,很显然获取过来的信息是一个ASCII码表的数字对应的信息
例如index ASCII表:[105 110 100 101 120 10], 10是换行符
\n
$ .\2-http-client.exe
data: index
data: [60 104 49 62 105 110 100 101 120 60 47 104 49 62 10]
检测http服务器状态使用http方法 Head, 只获取头部信息
package main
import (
"fmt"
"net/http"
)
var url = []string{
"http://www.baidu.com",
"http://taobao.com",
"http://google.com",
}
func main() {
for _, v := range url {
c := http.Client{}
res, err := http.Head(v)
if err != nil {
fmt.Println("get head failed, err:", err)
continue
}
fmt.Printf("head success , status:%v\n", res.Status)
}
}
编译并运行
$ go build go_dev/day10/example/http_head
$ ./http_head
head success , status:200 OK
head success , status:200 OK
get head failed, err: Head http://google.com: dial tcp 216.58.200.46:80: i/o timeout
发现超时时间过长,调整超时时间方法
一般检测一个网站,一秒钟没有返回就认为改网站故障
调整在
net
底层设置超时时间,这个设置比较底层
package main
import (
"fmt"
"net"
"net/http"
"time"
)
var url = []string{
"http://www.baidu.com",
"http://google.com",
"http://taobao.com",
}
func timeout(network, addr string) (net.Conn, error) {
timeout := time.Second
return net.DialTimeout(network, addr, timeout)
}
func main() {
for _, v := range url {
c := http.Client{
Transport: &http.Transport{
Dial: timeout,
},
}
fmt.Println()
fmt.Println(time.Now())
res, err := c.Head(v)
if err != nil {
fmt.Println("get head failed, err:", err)
continue
}
fmt.Printf("head success , status:%v\n", res.Status)
}
}
更简单方法调整超时时间
在
http.Client
结构体设置超时时间,这个更简单
package main
import (
"fmt"
"net/http"
"time"
)
var url = []string{
"http://www.baidu.com",
"http://www.google.com.hk",
"http://www.jd.com",
}
func main() {
client := http.Client{
Timeout: time.Duration(time.Second),
}
for _, v := range url {
fmt.Println()
fmt.Println(time.Now())
resp, err := client.Head(v)
if err != nil {
fmt.Printf("head %s failed, err:%v\n", v, err)
continue
}
fmt.Printf("%s head success, status:%v\n", v, resp.Status)
}
}
编译并运行
$ go build go_dev/day10/example/http_head
$ ./http_head
2017-08-08 23:18:35.329123548 +0800 CST
head success , status:200 OK
2017-08-08 23:18:35.339484242 +0800 CST
get head failed, err: Head http://google.com: dial tcp [2404:6800:4008:802::200e]:80: i/o timeout
2017-08-08 23:18:36.343658858 +0800 CST
head success , status:200 OK
网站检测超时时间1秒
http.Request.ParseFrom()
, 解析from表单http.Request.From
, 返回一个数组,获取里面的值需要通过下标来获取:request.Form["username"][0]
http.Request.FromValue(name)
, 获取一个标签为name的值package main
import (
"fmt"
"io"
"net/http"
)
const from = `
`
func simpleServer(w http.ResponseWriter, p *http.Request) {
io.WriteString(w, "hello world
")
}
func fromServer(w http.ResponseWriter, request *http.Request) {
w.Header().Set("Content-Type", "text/html")
switch request.Method {
case "GET":
io.WriteString(w, from)
case "POST":
// 解析form
request.ParseForm()
// request.From[username] 返回一个数组,必须要写具体的那个下标的元素
io.WriteString(w, request.Form["username"][0])
io.WriteString(w, "\n")
// request.FromValue 获取一个指定的 name="password"的标签的值
io.WriteString(w, request.FormValue("password"))
}
}
func main() {
http.HandleFunc("/test", simpleServer)
http.HandleFunc("/from", fromServer)
err := http.ListenAndServe("0.0.0.0:8000", nil)
if err != nil {
fmt.Println("http server failed...")
return
}
}
编译并运行
$ go build go_dev/day10/exercises/3-http-from
$ ./3-http-from
打开浏览器测试是否提交的表单又重新写到了返回的页面了
适合场景
- 其中一个页面出现异常,不会引起整个web服务器的异常退出
- 类似python的装饰器等功能都可以使用这个
主要实现是在执行url函数前添加了一个异常捕捉的函数
package main
import (
"fmt"
"net/http"
)
func index(writer http.ResponseWriter, request *http.Request) {
fmt.Println("page --> index")
fmt.Fprintln(writer, "welcome index
")
}
func login(writer http.ResponseWriter, request *http.Request) {
panic("user logiun page panic...")
}
func logPanic(handle http.HandlerFunc) http.HandlerFunc {
return func(writer http.ResponseWriter, request *http.Request) {
defer func() {
if x := recover(); x != nil {
fmt.Printf("[%v] caught panic: %v\n", request.RemoteAddr, x)
}
}()
handle(writer, request)
}
}
func main() {
http.HandleFunc("/", logPanic(index))
http.HandleFunc("/login", logPanic(login))
err := http.ListenAndServe("0.0.0.0:8000", nil)
if err != nil {
fmt.Println("server failed ...")
return
}
}
编译并测试(访问/login
异常,但访问/
正常返回)
$ go build go_dev/day10/exercises/4-http-panic
$ .\4-http-panic.exe