分享
  1. 首页
  2. 文章

golang 基础(27)http

zidea · · 1747 次点击 · · 开始浏览
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

golang_real.jpg

HTTP 编程

Http 可能使我们最熟悉的网络协议了吧,那么我们知道他全称吗?超文本传输协议,当初最开始写 html 时候看到这个名词有点 confusing。在 Go 语言标准库内建提供 net/http 包,涵盖了 HTTP 客户端和服务端的具体实现。

  • 使用 http 客户端发送请求
  • 使用http.Client控制请求头部等
  • 使用httputil简化工作

客户端请求

Get 请求

在 go 语言中实现简洁HTTP 客户端无需额外添加第三方包。

express eserver --pug --git --css less
cd eserver
npm install
npm start

这里用 express 简单创建了服务,来模拟客户端行为。

import(
 "net/http"
 "io"
 "os"
)
func main() {
 resp,err := http.Get("http://localhost:3000")
 if err != nil{
 return
 }
 defer resp.Body.Close()
 io.Copy(os.Stdout,resp.Body)
}
  • 使用 http.Get发起GET请求
  • 如果请求失败就return
  • defer 可以在退出时对资源进行关闭
  • 最后将获取内容resp.Body()在控制台进行输出

如果大家没有启动服务器,可以尝试请求百度一下

func main() {
 resp,err := http.Get("http://www.baidu.com")
 if err != nil {
 panic(err)
 }
 defer resp.Body.Close()
 s, err := httputil.DumpResponse(resp, true) //[]byte
 if err != nil{
 panic(err)
 }
 fmt.Printf("%s\n",s)
}

我们可以使用httputil.DumpResponse将 resp 装换为 []byte 输出

request, err := http.NewRequest(
 http.MethodGet,
 "http://www.baidu.com",
 nil)
 request.Header.Add("User-Agent",
 "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1")
 resp,err := http.DefaultClient.Do(request);
 if err != nil {
 panic(err)
 }

对 request 和 http 进行一些控制,我们想让我们client访问百度的手机版

Post 请求
router.post('/',function(req,res,next){
 console.log(req.body);
 console.log(req.baseUrl)
 res.send("ok")
})
 resp, err := http.Post("http://localhost:3000/users",
 "application/x-www-form-urlencoded",strings.NewReader("name=zidea"))
 if err != nil {
 fmt.Println(err)
 }
 
 defer resp.Body.Close()
 body, err := ioutil.ReadAll(resp.Body)
 if err != nil {
 // handle error
 }
 
 fmt.Println(string(body))

我们通常会发起表单请求,在 go 语言中为我们提供PostForm来轻松实现提交表单的请求

resp, err := http.PostForm("http://localhost:3000/users",url.Values{"title":{"angular"}, "author": {"zidea"}})
 if err != nil { 
 return
 }

自定义Client

在 go 语言中提供http.Gethttp.Post方法外,还提供一些方法让我们自定义请求体Request

 author := make(map[string]interface{})
 author["name"]="zidea"
 author["age"]=30
 bytesData, err := json.Marshal(author)
 if err != nil{
 fmt.Println(err.Error())
 return
 }
 reader := bytes.NewReader(bytesData)
 url := "http://localhost:3000/users"
 request, err := http.NewRequest("POST",url,reader)
 if err != nil{
 fmt.Println(err.Error())
 return
 }
 request.Header.Set("Content-Type", "application/json;charset=UTF-8")
 client := http.Client{}
 resp, err := client.Do(request)
 if err != nil {
 fmt.Println(err.Error())
 return
 }
 respBytes, err := ioutil.ReadAll(resp.Body)
 if err != nil {
 fmt.Println(err.Error())
 return
 }
 str := (*string)(unsafe.Pointer(&respBytes))
 fmt.Println(*str)
  • 通过 go 语言内置的encoding/json我们可以将 map 格式数据轻松转为 Json 的数据格式。
func Marshal(v interface{}) ([]byte, error)

Marshal这个方法接受接口而返回一个[]byte
具体可以参照 golang 网络编程(10)文本处理

  • 创建一个 request 请求体
func NewRequest(method, url string, body io.Reader) (*Request, error)

我们看 NewRequest 源码了解到,方法接受三个参数

  • 方法名
  • 请求地址
  • io.Reader
    前两个我们很容就可以搞定,而第三参数我们需要创建 reader 来传入。因为Marshal返回的是[]byte所以我们需要一个bytes.NewReader来返回一个我们想要 reader
func NewReader(b []byte) *Reader { return &Reader{b, 0, -1} }
  • 创建好了 request 对象,我们就可以设置其 header 内容。
 str := (*string)(unsafe.Pointer(&respBytes))
 fmt.Println(*str)

这段代码大家可能感觉陌生,这个有点接近底层,随后分享有关unsafe.Pointer用法。这里大家可以忽略他,仅认为这样做有利于内存优化而已。

  • 使用net/http包http.Client对象的Do()方法来实现

有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:zidea

查看原文:golang 基础(27)http

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

关注微信
1747 次点击
暂无回复
添加一条新回复 (您需要 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传

用户登录

没有账号?注册
(追記) (追記ここまで)

今日阅读排行

    加载中
(追記) (追記ここまで)

一周阅读排行

    加载中

关注我

  • 扫码关注领全套学习资料 关注微信公众号
  • 加入 QQ 群:
    • 192706294(已满)
    • 731990104(已满)
    • 798786647(已满)
    • 729884609(已满)
    • 977810755(已满)
    • 815126783(已满)
    • 812540095(已满)
    • 1006366459(已满)
    • 692541889

  • 关注微信公众号
  • 加入微信群:liuxiaoyan-s,备注入群
  • 也欢迎加入知识星球 Go粉丝们(免费)

给该专栏投稿 写篇新文章

每篇文章有总共有 5 次投稿机会

收入到我管理的专栏 新建专栏