Go | http部分前置知识 | 笔记心得

73 阅读5分钟

客户端请求

做法1 | http.NewRequest ()

package main

import (
	"fmt"
	"io"
	"net/http"
)

func main() {
	testHttpNewRequst()
}
func testHttpNewRequst() {
	// 1.建立客户端
	client := http.Client{}

	// 2.建立请求
	// method, url string, body io.Reader
	req,err:=http.NewRequest("GET","https://learnku.com/go/c/translations",nil)
	CheckErr(err)

	// 3.客户端发送请求
	response,err:=client.Do(req)
	CheckErr(err)
	defer response.Body.Close()
	
	// 4.提取数据
	if response.StatusCode==200{
		data,err:=io.ReadAll(response.Body)
		CheckErr(err)
		fmt.Println(string(data))
	}else{
		fmt.Println("网络访问失败!状态码:",response.StatusCode)
	}
}

func CheckErr(err error){
	defer func ()  {
		if ins,ok:=recover().(error);ok{
			fmt.Println("程序异常!",ins.Error())
		}
	}()
	if err!=nil{
		panic(err)
	}
}

做法2 | client. Get()

package main

import (
	"fmt"
	"io"
	"net/http"
)

func main() {
	testClientGet()
}
func testClientGet() {
	// 1. 建立客户端
	client := http.Client{}
	// 2. 使用客户端发起请求
	res,err:=client.Get("https://learnku.com/go/c/translations")
	CheckErr(err)
	defer res.Body.Close()

	// 3.提取数据
	if res.StatusCode==200{
		data,err:=io.ReadAll(res.Body)
		CheckErr(err)
		fmt.Println(string(data))
	}else{
		fmt.Println("网络访问失败!状态码:",res.StatusCode)
	}
}
func CheckErr(err error){
	defer func ()  {
		if ins,ok:=recover().(error);ok{
			fmt.Println("程序异常!",ins.Error())
		}
	}()
	if err!=nil{
		panic(err)
	}
}

做法3 | Http.Get()

package main

import (
	"fmt"
	"io"
	"net/http"
)

func main() {
	testClientGet()
}
func testClientGet() {
	// 1. 使用http发起请求! 还是用到的 DefaultClient 而defaultclient是
	// var DefaultClient = &Client{}
	res,err:=http.Get("https://learnku.com/go/c/translations")
	CheckErr(err)
	defer res.Body.Close()

	// 2. 提取数据
	if res.StatusCode==200{
		data,err:=io.ReadAll(res.Body)
		CheckErr(err)
		fmt.Println(string(data))
	}else{
		fmt.Println("网络访问失败!状态码:",res.StatusCode)
	}
}
func CheckErr(err error){
	defer func ()  {
		if ins,ok:=recover().(error);ok{
			fmt.Println("程序异常!",ins.Error())
		}
	}()
	if err!=nil{
		panic(err)
	}
}

补充一下 post 做法 | http.NewRequest ()

package main

import (
	"fmt"
	"io"
	"net/http"
	"strings"
)

func main() {
	// 测试网站总结 https://www.jianshu.com/p/cf5b0b7b5dbf
	url := "https://httpbin.org/post"
	data:=strings.NewReader("This is the data to be submitted!")
	testClientGet(url,data)
}
func testClientGet(url string,data *strings.Reader) {
	// 1. 建立客户端
	client := http.Client{}
	// 2. 使用客户端发起请求
	r,err:=http.NewRequest("POST",url,data)
	CheckErr(err)
	res, err := client.Do(r)
	CheckErr(err)
	defer res.Body.Close()

	// 3.提取数据
	if res.StatusCode == 200 {
		data, err := io.ReadAll(res.Body)
		CheckErr(err)
		fmt.Println(string(data))
	} else {
		fmt.Println("网络访问失败!状态码:", res.StatusCode)
	}
}
func CheckErr(err error) {
	defer func() {
		if ins, ok := recover().(error); ok {
			fmt.Println("程序异常!", ins.Error())
		}
	}()
	if err != nil {
		panic(err)
	}
}

服务端接受

操作1 | http. FileServer ()

package main

import "net/http"

// 文件服务器 做法
// 1. http.FileServer()搭建的服务器只提供静态文件的访问。
//      因为这种web服务只支持静态文件访问
//		会返回一个 http.Handler

// 2. http.ListenAndServe()函数用来启动Web服务,绑定并监听http端口
// ListenAndServe listens on the TCP network address addr and then calls
// Serve with handler to handle requests on incoming connections.
// Accepted connections are configured to enable TCP keep-alives.
//
// The handler is typically nil, in which case the DefaultServeMux is used.
//
// ListenAndServe always returns a non-nil error.
// func ListenAndServe(addr string, handler Handler) error {
// 		server := &Server{Addr: addr, Handler: handler}
// 		return server.ListenAndServe()
// }
// 其中headle 接口的是 实现 处理
// 只需要实现了 serveHttp这个方法就是 实现了 handler接口
// type Handler interface {
//	ServeHTTP(ResponseWriter, *Request)
//}
func main() {
	testFileServer()
}
func testFileServer() {
	http.ListenAndServe(":10086", http.FileServer(http.Dir("F:/go部分学习/网络开发/")))
}

操作2 | http.HandleFunc()

package main

import (
	"fmt"
	"net/http"
)

// http. HandleFunc()的作用是注册网络访问的路由。
// 因为它采用的是默认的路由分发任务方式,所以称之为默认的多路由分发服务
// HandleFunc registers the handler function for the given pattern
// in the DefaultServeMux.
// The documentation for ServeMux explains how patterns are matched.
// func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
// 	DefaultServeMux.HandleFunc(pattern, handler)
// }
// 关于serverMux
// ServeMux also takes care of sanitizing the URL request path and the Host
// header, stripping the port number and redirecting any request containing . or
// .. elements or repeated slashes to an equivalent, cleaner URL.
func main() {
	http.HandleFunc("/index",IndexHandler)
	// The handler is typically nil, in which case the DefaultServeMux is used.
	err:=http.ListenAndServe(":10086",nil)
	fmt.Println(err)
	
}
//handler func(ResponseWriter, *Request)
func IndexHandler(w http.ResponseWriter,r *http.Request){
	fmt.Println("/index====")
	w.Write([]byte("<h1>默认首页信息</h1>"))
}

补充

ServeMux

// ServeMux is an HTTP request multiplexer.
// It matches the URL of each incoming request against a list of registered
// patterns and calls the handler for the pattern that
// most closely matches the URL.
//
// Patterns name fixed, rooted paths, like "/favicon.ico",
// or rooted subtrees, like "/images/" (note the trailing slash).
// Longer patterns take precedence over shorter ones, so that
// if there are handlers registered for both "/images/"
// and "/images/thumbnails/", the latter handler will be
// called for paths beginning "/images/thumbnails/" and the
// former will receive requests for any other paths in the
// "/images/" subtree.
//
// Note that since a pattern ending in a slash names a rooted subtree,
// the pattern "/" matches all paths not matched by other registered
// patterns, not just the URL with Path == "/".
//
// If a subtree has been registered and a request is received naming the
// subtree root without its trailing slash, ServeMux redirects that
// request to the subtree root (adding the trailing slash). This behavior can
// be overridden with a separate registration for the path without
// the trailing slash. For example, registering "/images/" causes ServeMux
// to redirect a request for "/images" to "/images/", unless "/images" has
// been registered separately.
//
// Patterns may optionally begin with a host name, restricting matches to
// URLs on that host only. Host-specific patterns take precedence over
// general patterns, so that a handler might register for the two patterns
// "/codesearch" and "codesearch.google.com/" without also taking over
// requests for "http://www.google.com/".
//
// ServeMux also takes care of sanitizing the URL request path and the Host
// header, stripping the port number and redirecting any request containing . or
// .. elements or repeated slashes to an equivalent, cleaner URL.
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
}

type muxEntry struct {
	h       Handler
	pattern string
}

DefaultServeMux与ServeMux分配

// NewServeMux allocates and returns a new ServeMux.
func NewServeMux() *ServeMux { return new(ServeMux) }

// DefaultServeMux is the default ServeMux used by Serve.
var DefaultServeMux = &defaultServeMux

var defaultServeMux ServeMux

小总结

package main

import (
	"fmt"
	"net/http"
)

// http. HandleFunc()的作用是注册网络访问的路由。
// 因为它采用的是默认的路由分发任务方式,所以称之为默认的多路由分发服务

// 总结部分:
// 这个http.NewServeMux() 生成一个自己的方案 然后自己来实现路由转发细节处理 (留给自己的)
// 而DefaultServeMux的细节化操作是go已经做好了的

// http.NewServeMux()仍然使用原来的结构体,只是其中的MUXEntry已经被替换为map容器。
// 它可以帮助你根据不同的URL进行路由,并且能够更好地处理请求。
// 显然 简单的开发是不需要这么花里胡哨的 (<-自己写框架的话 可以试试)
func main() {
	http.HandleFunc("/index",IndexHandler)
	// The handler is typically nil, in which case the DefaultServeMux is used.
	err:=http.ListenAndServe(":10086",nil)
	fmt.Println(err)
	// http.NewServeMux()
}
//handler func(ResponseWriter, *Request)
func IndexHandler(w http.ResponseWriter,r *http.Request){
	fmt.Println("/index====")
	w.Write([]byte("<h1>默认首页信息</h1>"))
}

获取客户端请求数据

Requst部分方法即可

补充Cookie结构体

// A Cookie represents an HTTP cookie as sent in the Set-Cookie header of an
// HTTP response or the Cookie header of an HTTP request.
//
// See https://tools.ietf.org/html/rfc6265 for details.
type Cookie struct {
	Name  string
	Value string

	Path       string    // optional
	Domain     string    // optional
	Expires    time.Time // optional
	RawExpires string    // for reading cookies only

	// MaxAge=0 means no 'Max-Age' attribute specified.
	// MaxAge<0 means delete cookie now, equivalently 'Max-Age: 0'
	// MaxAge>0 means Max-Age attribute present and given in seconds
	MaxAge   int
	Secure   bool
	HttpOnly bool
	SameSite SameSite
	Raw      string
	Unparsed []string // Raw text of unparsed attribute-value pairs
}

附录 | 参考 | 好文

  1. 测试请求
  2. 官方文档
  3. 微信读书中go开发实战
  4. 掘金大佬