golang中的标准库http
Go语言内置的net/http包十分的优秀,提供了HTTP客户端和服务端的实现。
http客户端
基本的HTTP/HTTPS请求 Get、Head、Post和PostForm函数发出HTTP/HTTPS请求。
resp, err := http.Get("http://5lmh.com/")
...
resp, err := http.Post("http://5lmh.com/upload", "image/jpeg", &buf)
...
resp, err := http.PostForm("http://5lmh.com/form",
url.Values{"key": {"Value"}, "id": {"123"}})
程序在使用完response后必须关闭回复的主体。
resp, err := http.Get("http://5lmh.com/")
if err != nil {
// handle error
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
// ...
GET请求示例
使用net/http包编写一个简单的发送HTTP请求的Client端,代码如下:
func main() {
resp, err := http.Get("https://www.liwenzhou.com")
if err != nil {
fmt.Println(err.Error())
return
}
// 使用完response之后必须关闭使用的主体
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println(err.Error())
return
}
fmt.Println(string(body))
}
将上面的代码保存之后编译成可执行文件,执行之后就能在终端打印liwenzhou.com网站首页的内容了,我们的浏览器其实就是一个发送和接收HTTP协议数据的客户端,我们平时通过浏览器访问网页其实就是从网站的服务器接收HTTP数据,然后浏览器会按照HTML、CSS等规则将网页渲染展示出来。
带参数的GET请求示例
关于GET请求的参数需要使用Go语言内置的net/url这个标准库来处理。
- server.go
func main() {
http.HandleFunc("/", SayHello)
if err := http.ListenAndServe(":8000", nil); err != nil {
fmt.Println(err.Error())
return
}
}
func SayHello(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
data := r.URL.Query()
name := data.Get("name")
age := data.Get("age")
fmt.Println(name, age)
answer := `{"status": "ok"}`
w.Write([]byte(answer))
}
- client.go
func main() {
//resp, err := http.Get("http://127.0.0.1:8000")
apiUrl := "http://127.0.0.1:8000"
data := url.Values{} // 类型:type Values map[string][]string
data.Set("name", "张三")
data.Set("age", "18")
u, err := url.ParseRequestURI(apiUrl)
if err != nil {
fmt.Println(err.Error())
return
}
u.RawQuery = data.Encode()
fmt.Println(u.String())
resp, err := http.Get(u.String())
if err != nil {
fmt.Println(err.Error())
return
}
defer resp.Body.Close()
/*
reader := bufio.NewReader(resp.Body)
buf := make([]byte, 1000)
n, _ := reader.Read(buf)
fmt.Println(buf[:n])
*/
// ioutil.ReadAll() 代替了上面这段
buf, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println(err.Error())
return
}
fmt.Println(string(buf))
}
POST请求示例
上面演示了使用net/http包发送GET请求的示例,发送POST请求的示例代码如下:
POST表单请求数据
- server.go
func main() {
http.HandleFunc("/", SayHello)
if err := http.ListenAndServe(":8000", nil); err != nil {
fmt.Println(err.Error())
return
}
}
func SayHello(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
// 1. 请求类型是application/x-www-form-urlencoded时解析form数据
r.ParseForm()
fmt.Println(r.PostForm)
fmt.Println(r.PostForm.Get("name"), r.PostForm.Get("age"))
answer := `{"status": "ok"}`
w.Write([]byte(answer))
}
- client.go
func main() {
apiUrl := "http://127.0.0.1:8000"
data := url.Values{} // 类型:type Values map[string][]string
data.Set("name", "张三")
data.Set("age", "18")
resp, err := http.PostForm(apiUrl, data)
if err != nil {
fmt.Println(err.Error())
return
}
defer resp.Body.Close()
buf, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println(err.Error())
return
}
fmt.Println(string(buf))
}
POST json提交数据
- server.go
func main() {
http.HandleFunc("/", SayHello)
if err := http.ListenAndServe(":8000", nil); err != nil {
fmt.Println(err.Error())
return
}
}
func SayHello(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
// 1. 请求类型是application/json时从r.Body读取数据
buf, err := ioutil.ReadAll(r.Body)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(string(buf))
answer := `{"status": "ok"}`
w.Write([]byte(answer))
}
- client.go
func main() {
apiUrl := "http://127.0.0.1:8000"
contentType := "application/json"
data := `{"name": "haha", "age": 123}`
resp, err := http.Post(apiUrl, contentType, strings.NewReader(data))
if err != nil {
fmt.Println(err.Error())
return
}
defer resp.Body.Close()
buf, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println(err.Error())
return
}
fmt.Println(string(buf))
}
默认的server示例
使用Go语言中的net/http包来编写一个简单的接收HTTP请求的Server端示例,net/http包是对net包的进一步封装,专门用来处理HTTP协议的数据。具体的代码如下:
func main() {
http.HandleFunc("/", SayHello)
if err := http.ListenAndServe(":8000", nil); err != nil {
fmt.Println(err.Error())
return
}
}
func SayHello(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
// 1. 请求类型是application/json时从r.Body读取数据
buf, err := ioutil.ReadAll(r.Body)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(string(buf))
fmt.Fprintln(w, `{"status": "ok"}`)
}
自定义server
要管理服务端的行为,可以创建一个自定义的Server:
// 定义字段保存路由与视图函数之间的映射关系
var routerMapFunc = make(map[string]func(http.ResponseWriter, *http.Request))
type CustomerHandler struct {}
func (*CustomerHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if viewFunc, ok := routerMapFunc[r.URL.String()]; ok {
viewFunc(w, r)
} else {
w.WriteHeader(http.StatusNotFound)
w.Write([]byte("404 not found"))
}
}
func main() {
s := &http.Server{
Addr: ":8000",
Handler: &CustomerHandler{},
ReadTimeout: 10 * time.Second,
WriteTimeout: 10 * time.Second,
MaxHeaderBytes: 2 << 20, // 1048576个字节,也就是1M
}
// 注册路由
routerMapFunc["/index"] = IndexView
if err := s.ListenAndServe(); err != nil {
fmt.Println(err.Error())
return
}
}
func IndexView(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, `{"status": "OK", "msg": "哈哈哈"}`)
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)