Golang 学习笔记(一) - HTTP 客户端 - 基础

BroQiang 1年前 访问:754 评论:0 关注:0

Go 封装了非常方便的客户端方法,不再需要借助第三方包,就可以实现客户端的请求。本篇文章主要将的是 Get 、 Post 、PostForm 三个基础的方法。

文档已经在 github 创建仓库,欢迎围观,欢迎修正。

Get

github

这个方法非常的简单,就是从指定的地址获取到内容,可以简单的理解成我们用浏览器打开一个页面。

Get 函数

语法:

Get(url string) (resp *Response, err error)

参数:

  • 字符串类型的 url 地址,需要注意的是这里要是完整地址,要加上 http://https:// 的地址

返回值:

  • *Response 如果获取到了数据,会将数据保存在 Response 中

  • error 如果请求数据的时候出现错误,会返回一个 error ,并将具体的错误记录到 error 中

另外一种方式 Get 方法

可以通过 client 结构体的 Get() 方法获取数据,其实两种方式是一样的,Get() 函数也是调用的结构体中的 Get() 方法。详细的使用可以见示例中的用法

示例:

client.go

package main

import (
    "net/http"
    "log"
    "io/ioutil"
    "os"
    "fmt"
)

const url  = "https://broqiang.com"

func main() {
    // 方式一,直接通过 Get 函数
    resp, err := http.Get(url)
    ErrPrint(err)
    defer resp.Body.Close()

    // 拿到数据
    bytes, err := ioutil.ReadAll(resp.Body)
    ErrPrint(err)

    // 这里要格式化再输出,因为 ReadAll 返回的是字节切片
    fmt.Println("------------- 方法一 ---------------")
    fmt.Printf("%s",bytes)

    // 方式二,通过 client 结构体的 Get 方法
    client := new(http.Client)
    // 或
    client = &http.Client{}

    resp, err = client.Get(url)
    ErrPrint(err)
    defer resp.Body.Close()

    res, err := ioutil.ReadAll(resp.Body)
    ErrPrint(err)
    fmt.Println("\n\n\n------------- 方法二 ---------------")
    fmt.Printf("%s",res)
}

func ErrPrint(err error)  {
    if err != nil {
        log.Fatalln(err)
        os.Exit(1)
    }
}

Post

github

这个方法也比较简单,就是通过 Post 方式和服务器端交互。

POST 函数

语法:

(url string, contentType string, body io.Reader) (resp *Response, err error)

参数:

  • 字符串类型的 url 地址,需要注意的是这里要是完整地址,要加上 http://https:// 的地址

  • 字符串类型的 contentType ,Post 提交数据的类型,常见的有下面 4 种:

    • application/x-www-form-urlencoded 不设置 enctype 属性的原生 form 表单提交方式。

    • multipart/form-data 上传文件时的数据提交方式,相当于 form 表单的 enctype 等于 multipart/form-data 。

    • application/json 用来告诉服务端消息主体是序列化后的 JSON 字符串。

    • text/xml 它是一种使用 HTTP 作为传输协议,XML 作为编码方式的远程调用规范,和 json 作用类型。

  • 实现了 io.Reader 接口的数据。 如: 可以通过 strings.NewReader() 方法将普通字符串实现 io.Reader 接口。

返回值:

  • *Response 如果获取到了数据,会将数据保存在 Response 中

  • error 如果请求数据的时候出现错误,会返回一个 error ,并将具体的错误记录到 error 中

另外一种方式 Post 方法

可以通过 client 结构体的 Post() 方法获取数据,其实两种方式是一样的,Post() 函数也是调用的结构体中的 Post() 方法。详细的使用可以见示例中的用法

示例:

这个示例要和服务器端交互数据,所以要有一个服务器端和一个客户端,服务器端见目录中的服务器端内容(如果你很快就发现了这个文档,可能还没来得及写服务器端)。

服务器端代码

server.go

可以通过 http://localhost:8080/hello 来访问服务器端,但是要是 Post 方式才可以。测试的时候注意要先启动服务器端,再启动客户端。

package main

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

func main() {
    http.HandleFunc("/hello", func(w http.ResponseWriter, req *http.Request) {
        if req.Method == "POST" {
            fmt.Fprintf(w,"Hello %s\n",req.FormValue("name"))
            return
        }

        http.NotFound(w,req)
    })

    log.Fatalf("%v",http.ListenAndServe("localhost:8080",nil))
}

客户端代码

client.go

package main

import (
    "log"
    "os"
    "net/http"
    "strings"
    "fmt"
    "io/ioutil"
    "io"
)

const url  = "http://localhost:8080/hello"

func main() {
    // 方式一,直接通过 Post 函数
    fmt.Println("------------- 方法一 ---------------")
    resp, err := http.Post(url,"application/x-www-form-urlencoded",
        strings.NewReader("name=Bro Qiang"))
    ErrPrint(err)
    defer resp.Body.Close()

    DataPrint(resp.Body)

    // 方式二,通过 client 结构体中的 Post 方法
    fmt.Println("------------- 方法二 ---------------")
    client := &http.Client{}
    resp, err = client.Post(url,"application/x-www-form-urlencoded",
        strings.NewReader("name=New Bro Qiang"))
    ErrPrint(err)
    defer resp.Body.Close()

    DataPrint(resp.Body)
}

func DataPrint(body io.ReadCloser) {
    // 拿到数据
    bytes, err := ioutil.ReadAll(body)
    ErrPrint(err)

    // 这里要格式化再输出,因为 ReadAll 返回的是字节切片
    fmt.Printf("%s",bytes)
}

func ErrPrint(err error)  {
    if err != nil {
        log.Fatalln(err)
        os.Exit(1)
    }
}

PostForm

github

这个方法是通过 Post 方式向服务器端提交一个 form 表单,和 html 中的 form 表单提交类型。

PostForm 函数

语法:

PostForm(url string, data url.Values) (resp *Response, err error)

参数:

  • 字符串类型的 url 地址,需要注意的是这里要是完整地址,要加上 http://https:// 的地址

  • url.Values 类型的数据, 它的类型实际是一个 map[string][]string

返回值:

  • *Response 如果获取到了数据,会将数据保存在 Response 中

  • error 如果请求数据的时候出现错误,会返回一个 error ,并将具体的错误记录到 error 中

另外一种方式 PostForm 方法

可以通过 client 结构体的 PostForm() 方法获取数据,其实两种方式是一样的,PostForm() 函数也是调用的结构体中的 PostForm() 方法。详细的使用可以见示例中的用法

示例:

创建一个服务器端,用来接收 from 表单,并将数据在控制台打印,并给客户端返回是否成功。

创建一个客户端,用来向服务器端发送 form 表单。

注意: 客户端的 resp.Body 不要忘记关闭。

服务器端

server.go

package main

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

func main() {
    http.HandleFunc("/form", MyForm)

    log.Fatalf("%v",
        http.ListenAndServe("localhost:8080", nil))
}

func MyForm(w http.ResponseWriter, r *http.Request) {
    err := r.ParseForm()
    if err != nil {
        http.Error(w, http.StatusText(http.StatusInternalServerError),
            http.StatusInternalServerError)
        return
    }

    formData := r.Form
    log.Printf("收到的数据: %v", formData)

    fmt.Fprintf(w, "提交成功")
}

客户端代码

client.go

package main

import (
    "fmt"
    "io"
    "io/ioutil"
    "log"
    "net/http"
    "os"
)

const url = "http://localhost:8080/form"

func main() {
    data := map[string][]string{"name": {"Bro Qiang"}, "gender": {"male"}}

    // 方法一:PostForm 函数
    resp, err := http.PostForm(url, data)
    ErrPrint(err)
    defer resp.Body.Close()

    DataPrint(resp.Body)

    // 方法二:client 结构体的 PostForm 方法
    client := &http.Client{}
    resp, err = client.PostForm(url, data)
    ErrPrint(err)
    defer resp.Body.Close()

    DataPrint(resp.Body)
}

func DataPrint(body io.ReadCloser) {
    // 拿到数据
    bytes, err := ioutil.ReadAll(body)
    ErrPrint(err)

    // 这里要格式化再输出,因为 ReadAll 返回的是字节切片
    fmt.Printf("%s\n", bytes)
}

func ErrPrint(err error) {
    if err != nil {
        log.Fatalln(err)
        os.Exit(1)
    }
}
评论

还没有人评论 ~

公告
博客正式从原来的 Github Page 迁移到这里,原本的内容可以通过 broqiang.github.io 访问
返回顶部