golang 基础(27)http

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()方法来实现
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 198,154评论 5 464
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,252评论 2 375
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 145,107评论 0 327
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,985评论 1 268
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,905评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,256评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,978评论 3 388
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,611评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,891评论 1 293
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,910评论 2 314
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,736评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,516评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,995评论 3 301
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,132评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,447评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,034评论 2 343
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,242评论 2 339

推荐阅读更多精彩内容