🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
[TOC] ## 语法 ### const <details> <summary>状态码</summary> ``` const ( StatusContinue = 100 // RFC 7231, 6.2.1 StatusSwitchingProtocols = 101 // RFC 7231, 6.2.2 StatusProcessing = 102 // RFC 2518, 10.1 StatusEarlyHints = 103 // RFC 8297 StatusOK = 200 // RFC 7231, 6.3.1 StatusCreated = 201 // RFC 7231, 6.3.2 StatusAccepted = 202 // RFC 7231, 6.3.3 StatusNonAuthoritativeInfo = 203 // RFC 7231, 6.3.4 StatusNoContent = 204 // RFC 7231, 6.3.5 StatusResetContent = 205 // RFC 7231, 6.3.6 StatusPartialContent = 206 // RFC 7233, 4.1 StatusMultiStatus = 207 // RFC 4918, 11.1 StatusAlreadyReported = 208 // RFC 5842, 7.1 StatusIMUsed = 226 // RFC 3229, 10.4.1 StatusMultipleChoices = 300 // RFC 7231, 6.4.1 StatusMovedPermanently = 301 // RFC 7231, 6.4.2 StatusFound = 302 // RFC 7231, 6.4.3 StatusSeeOther = 303 // RFC 7231, 6.4.4 StatusNotModified = 304 // RFC 7232, 4.1 StatusUseProxy = 305 // RFC 7231, 6.4.5 _ = 306 // RFC 7231, 6.4.6 (Unused) StatusTemporaryRedirect = 307 // RFC 7231, 6.4.7 StatusPermanentRedirect = 308 // RFC 7538, 3 StatusBadRequest = 400 // RFC 7231, 6.5.1 StatusUnauthorized = 401 // RFC 7235, 3.1 StatusPaymentRequired = 402 // RFC 7231, 6.5.2 StatusForbidden = 403 // RFC 7231, 6.5.3 StatusNotFound = 404 // RFC 7231, 6.5.4 StatusMethodNotAllowed = 405 // RFC 7231, 6.5.5 StatusNotAcceptable = 406 // RFC 7231, 6.5.6 StatusProxyAuthRequired = 407 // RFC 7235, 3.2 StatusRequestTimeout = 408 // RFC 7231, 6.5.7 StatusConflict = 409 // RFC 7231, 6.5.8 StatusGone = 410 // RFC 7231, 6.5.9 StatusLengthRequired = 411 // RFC 7231, 6.5.10 StatusPreconditionFailed = 412 // RFC 7232, 4.2 StatusRequestEntityTooLarge = 413 // RFC 7231, 6.5.11 StatusRequestURITooLong = 414 // RFC 7231, 6.5.12 StatusUnsupportedMediaType = 415 // RFC 7231, 6.5.13 StatusRequestedRangeNotSatisfiable = 416 // RFC 7233, 4.4 StatusExpectationFailed = 417 // RFC 7231, 6.5.14 StatusTeapot = 418 // RFC 7168, 2.3.3 StatusMisdirectedRequest = 421 // RFC 7540, 9.1.2 StatusUnprocessableEntity = 422 // RFC 4918, 11.2 StatusLocked = 423 // RFC 4918, 11.3 StatusFailedDependency = 424 // RFC 4918, 11.4 StatusTooEarly = 425 // RFC 8470, 5.2. StatusUpgradeRequired = 426 // RFC 7231, 6.5.15 StatusPreconditionRequired = 428 // RFC 6585, 3 StatusTooManyRequests = 429 // RFC 6585, 4 StatusRequestHeaderFieldsTooLarge = 431 // RFC 6585, 5 StatusUnavailableForLegalReasons = 451 // RFC 7725, 3 StatusInternalServerError = 500 // RFC 7231, 6.6.1 StatusNotImplemented = 501 // RFC 7231, 6.6.2 StatusBadGateway = 502 // RFC 7231, 6.6.3 StatusServiceUnavailable = 503 // RFC 7231, 6.6.4 StatusGatewayTimeout = 504 // RFC 7231, 6.6.5 StatusHTTPVersionNotSupported = 505 // RFC 7231, 6.6.6 StatusVariantAlsoNegotiates = 506 // RFC 2295, 8.1 StatusInsufficientStorage = 507 // RFC 4918, 11.5 StatusLoopDetected = 508 // RFC 5842, 7.2 StatusNotExtended = 510 // RFC 2774, 7 StatusNetworkAuthenticationRequired = 511 // RFC 6585, 6 ) ``` </details> <br /> ### func ``` // 修改header 如: "accept-encoding" -> "Accept-Encoding" func CanonicalHeaderKey(s string) string // 根据cotnent判断内容 如 data=`<HTML></HTML>` -> text/html; charset=utf-8 func DetectContentType(data []byte) string func Error(w ResponseWriter, error string, code int) func Handle(pattern string, handler Handler) func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) func ListenAndServe(addr string, handler Handler) error func ListenAndServeTLS(addr, certFile, keyFile string, handler Handler) error func MaxBytesReader(w ResponseWriter, r io.ReadCloser, n int64) io.ReadCloser func NotFound(w ResponseWriter, r *Request) func NotFoundHandler() // 如 "HTTP/1.0" -> (1, 0, true) func ParseHTTPVersion(vers string) (major, minor int, ok bool) // 如 "Mon, 04 Jan 2021 03:16:34 GMT" 解析为 time.Time func ParseTime(text string) (t time.Time, err error) // 通过代理访问 func ProxyFromEnvironment(req *Request) (*url.URL, error) func ProxyURL(fixedURL *url.URL) func(*Request) (*url.URL, error) // 跳转 如 " http.Redirect(w,r,"/file/upload/suc",http.StatusFound) " func Redirect(w ResponseWriter, r *Request, url string, code int) func Serve(l net.Listener, handler Handler) error func ServeTLS(l net.Listener, handler Handler, certFile, keyFile string) error func ServeContent(w ResponseWriter, req *Request, name string, modtime time.Time, ...) // 根据name 文件类型,展示文件内容,或下载 func ServeFile(w ResponseWriter, r *Request, name string) func SetCookie(w ResponseWriter, cookie *Cookie) func StatusText(code int) string func FileServer(root FileSystem) Handler func NotFoundHandler() Handler func RedirectHandler(url string, code int) Handler func StripPrefix(prefix string, h Handler) Handler func TimeoutHandler(h Handler, dt time.Duration, msg string) Handler ``` ### Type ``` type Client func (c *Client) CloseIdleConnections() func (c *Client) Do(req *Request) (*Response, error) func (c *Client) Get(url string) (resp *Response, err error) func (c *Client) Head(url string) (resp *Response, err error) func (c *Client) Post(url, contentType string, body io.Reader) (resp *Response, err error) func (c *Client) PostForm(url string, data url.Values) (resp *Response, err error) . type HandlerFunc func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) type Header func (h Header) Add(key, value string) func (h Header) Clone() Header func (h Header) Del(key string) func (h Header) Get(key string) string func (h Header) Set(key, value string) func (h Header) Values(key string) []string func (h Header) Write(w io.Writer) error func (h Header) WriteSubset(w io.Writer, exclude map[string]bool) error type Request func NewRequest(method, url string, body io.Reader) (*Request, error) func NewRequestWithContext(ctx context.Context, method, url string, body io.Reader) (*Request, error) func ReadRequest(b *bufio.Reader) (*Request, error) func (r *Request) AddCookie(c *Cookie) func (r *Request) BasicAuth() (username, password string, ok bool) func (r *Request) Clone(ctx context.Context) *Request func (r *Request) Context() context.Context func (r *Request) Cookie(name string) (*Cookie, error) func (r *Request) Cookies() []*Cookie func (r *Request) FormFile(key string) (multipart.File, *multipart.FileHeader, error) func (r *Request) FormValue(key string) string func (r *Request) MultipartReader() (*multipart.Reader, error) func (r *Request) ParseForm() error func (r *Request) ParseMultipartForm(maxMemory int64) error func (r *Request) PostFormValue(key string) string func (r *Request) ProtoAtLeast(major, minor int) bool func (r *Request) Referer() string func (r *Request) SetBasicAuth(username, password string) func (r *Request) UserAgent() string func (r *Request) WithContext(ctx context.Context) *Request func (r *Request) Write(w io.Writer) error func (r *Request) WriteProxy(w io.Writer) error type Response func Get(url string) (resp *Response, err error) func Head(url string) (resp *Response, err error) func Post(url, contentType string, body io.Reader) (resp *Response, err error) func PostForm(url string, data url.Values) (resp *Response, err error) func ReadResponse(r *bufio.Reader, req *Request) (*Response, error) func (r *Response) Cookies() []*Cookie func (r *Response) Location() (*url.URL, error) func (r *Response) ProtoAtLeast(major, minor int) bool func (r *Response) Write(w io.Writer) error type ServeMux func NewServeMux() *ServeMux func (mux *ServeMux) Handle(pattern string, handler Handler) func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request)) func (mux *ServeMux) Handler(r *Request) (h Handler, pattern string) func (mux *ServeMux) ServeHTTP(w ResponseWriter, r *Request) type Server func (srv *Server) Close() error func (srv *Server) ListenAndServe() error func (srv *Server) ListenAndServeTLS(certFile, keyFile string) error func (srv *Server) RegisterOnShutdown(f func()) func (srv *Server) Serve(l net.Listener) error func (srv *Server) ServeTLS(l net.Listener, certFile, keyFile string) error func (srv *Server) SetKeepAlivesEnabled(v bool) func (srv *Server) Shutdown(ctx context.Context) error type Transport func (t *Transport) CancelRequest(req *Request) func (t *Transport) Clone() *Transport func (t *Transport) CloseIdleConnections() func (t *Transport) RegisterProtocol(scheme string, rt RoundTripper) func (t *Transport) RoundTrip(req *Request) (*Response, error) ``` ## 实例 ### hijack http劫持 劫持 http 后续自己完全处理connection,一般用于基于HTTP协议的rpc算一个,从HTTP升级到WebSocket ``` func handle1(w http.ResponseWriter, r *http.Request) { hj, _ := w.(http.Hijacker) conn, buf, _ := hj.Hijack() defer conn.Close() buf.WriteString("hello world") buf.Flush() } func handle2(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "hello world") } ``` 访问 ``` > curl -i http://localhost:9090/handle1 hello world > curl -i http://localhost:9090/handle2 HTTP/1.1 200 OK Date: Thu, 14 Jun 2018 07:51:31 GMT Content-Length: 11 Content-Type: text/plain; charset=utf-8 hello world ``` #### FormFile 单文件上传 ``` http.HandleFunc("/upload/", func(w http.ResponseWriter, r *http.Request) { //配置信息 formFile := "file" //form 表单中文件上传的名字 fileType := []string{".mp3", ".mp4"} //允许上传的文件类型 fileTypeStatus := false maxFileSize := int64(50 * 1024 * 1024) //最大文件上传 maxMemory := int64(50 << 20) //50*1024*1024 //最大内存上传的文件存储在maxMemory大小的内存里面,如果文件大小超过了maxMemory,那么剩下的部分将存储在系统的临时文件中 filePath := "./video/"//文件路径 if r.Method != http.MethodPost { w.Write([]byte("method is error")) return } r.Body = http.MaxBytesReader(w, r.Body, maxFileSize) e := r.ParseMultipartForm(maxMemory) if e != nil { w.Write([]byte(e.Error())) return } file, header, e := r.FormFile(formFile) if e != nil { w.Write([]byte(e.Error())) return } defer file.Close() //文件类型检查 for _, v := range fileType { if strings.HasSuffix(header.Filename, v) { fileTypeStatus = true //存在允许的类型 } } if !fileTypeStatus { w.Write([]byte("type is error")) return } //文件类型检查 end unix := strconv.Itoa(int(time.Now().Unix())) filepath := filePath + unix + "_" + header.Filename f, e := os.OpenFile(filepath, os.O_WRONLY|os.O_CREATE, 0666) if e != nil { w.Write([]byte(e.Error())) return } defer f.Close() io.Copy(f, file) w.Write([]byte("success")) }) ``` #### http.NewRequest 设置 http请求 ``` request, _ := http.NewRequest("get", "http://www.bilibili.com", nil) respone, _ := http.DefaultClient.Do(request) all, _ := ioutil.ReadAll(respone.Body) fmt.Printf("%+v\n", string(all)) ``` #### http.Transport 设置http 代理 <details> <summary>main.go</summary> ``` checkErr := func(err error) { if err != nil { log.Fatal(err) } } parse, err := url.Parse("http://127.0.0.1:1082") checkErr(err) t := &http.Transport{ Proxy: http.ProxyURL(parse), TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, } c := &http.Client{ Transport: t, Timeout: 10 * time.Second, } // 设置 request head 信息 request, err := http.NewRequest("get", "http://www.google.com/", nil) request.Header.Set("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36") request.Header.Set("Connection", "keep-alive") res, err := c.Do(request) checkErr(err) // simple ,无法设置head 头 //res, err := c.Get("http://www.google.com") //checkErr(err) //defer res.Body.Close() all, err := ioutil.ReadAll(res.Body) checkErr(err) fmt.Printf("%+v\n", string(all)) ``` </details> <br /> #### http.DefaultTransport 从环境获取代理 ``` req, _ := http.NewRequest("GET", "http://www.facebook.com/", nil) respone, err := http.DefaultTransport.RoundTrip(req) if err != nil { log.Fatal(err) } ``` ### 设置 handle 的方式 #### handleFunc ``` http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { io.WriteString(w, "hello world") }) ``` #### 自定义函数 ``` func newPeopleHandler() http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { fmt.Fprintln(w, "This is the people handler.") }) } mux.Handle("/resources/people/", newPeopleHandler()) ``` ### 结构体 实现 Handler 接口 ``` type countHandler struct { mu sync.Mutex // guards n n int } func (h *countHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { h.mu.Lock() defer h.mu.Unlock() h.n++ fmt.Fprintf(w, "count is %d\n", h.n) } func ExampleHandle() { http.Handle("/count", new(countHandler)) log.Fatal(http.ListenAndServe(":8080", nil)) } ``` ### 开启http 服务的方式 #### ListenAndServe ``` http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { io.WriteString(w, "hello world") }) http.ListenAndServe(":1234", nil) ``` #### http.ListenAndServeTLS ``` http.ListenAndServeTLS(":8443", "cert.pem", "key.pem", nil) ``` #### http.NewServeMux ``` func main() { mux := http.NewServeMux() mux.HandleFunc("/foo", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintln(w, "world") }) http.ListenAndServe(":1234", mux) } ``` #### http.Server ``` s := &http.Server{ Addr: ":1234", Handler: nil, ReadTimeout: 10 * time.Second, WriteTimeout: 10 * time.Second, MaxHeaderBytes: 1 << 20, } defer s.Close() s.SetKeepAlivesEnabled(true) idleConnsClosed := make(chan struct{}) go func() { sigint := make(chan os.Signal, 1) signal.Notify(sigint, os.Interrupt) <-sigint err := s.Shutdown(context.Background()) if err != nil { log.Print(err) } close(idleConnsClosed) }() // 退出前触发,可设置多个 s.RegisterOnShutdown(func() { fmt.Printf("%+v\n", "hello 1") }) s.RegisterOnShutdown(func() { fmt.Printf("%+v\n", "hello 2") }) if err := s.ListenAndServe(); err != nil { log.Println("quit:" + err.Error()) } <-idleConnsClosed ``` #### http.FileServer 开启文件服务 示例1:简单demo ``` http.ListenAndServe(":1234", http.FileServer(http.Dir("public"))) ``` 示例2:去掉前缀 ``` ├── main.go └── video └── test1.mp4 ``` ``` http.Handle("/video/",http.StripPrefix("/video/",http.FileServer(http.Dir("./video")))) //去掉 /video 前缀 http.ListenAndServe(":8090", nil) ``` 访问 `http://127.0.0.1:8090/video/test1.mp4` ### 创建带 timeout 的Requst ``` req, err := http.NewRequest("GET", uri, nil) if err != nil { log.Fatalf("http.NewRequest() failed with '%s'\n", err) } ctx, _ := context.WithTimeout(context.Background(), time.Millisecond*100) req = req.WithContext(ctx) ``` ### TimeoutHandler 带 timeout 的http ``` http.HandleFunc("/", test) timeoutHandler := http.TimeoutHandler(http.DefaultServeMux, 5 * time.Second, "timeout") http.ListenAndServe(":8080", timeoutHandler) ```