Contents

Go Http

Go 原生http库

Go语言内置的net/http包十分的优秀,提供了HTTP客户端和服务端的实现。

一、net/http介绍

Go语言内置的net/http包提供了HTTP客户端和服务端的实现。

HTTP协议

超文本传输协议(HTTP,HyperText Transfer Protocol)是互联网上应用最为广泛的一种网络传输协议,所有的WWW文件都必须遵守这个标准。设计HTTP最初的目的是为了提供一种发布和接收HTML页面的方法。

二、HTTP客户端

Get、Head、Post和PostForm函数发出HTTP/HTTPS请求。

resp, err := http.Get("http://example.com/")
...
resp, err := http.Post("http://example.com/upload", "image/jpeg", &buf)
...
resp, err := http.PostForm("http://example.com/form",
	url.Values{"key": {"Value"}, "id": {"123"}})

程序在使用完response后必须关闭回复的主体。

resp, err := http.Get("http://example.com/")
if err != nil {
	// handle error
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
// ...

GET请求示例

package main

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

func main() {
	resp, err := http.Get("https://httpbin.org/uuid")
	if err != nil {
		fmt.Printf("get failed, err:%v\n", err)
		return
	}
	defer resp.Body.Close()
	body, err := io.ReadAll(resp.Body)
	if err != nil {
		fmt.Printf("read from resp.Body failed, err:%v\n", err)
		return
	}
	fmt.Print(string(body))
}

自定义请求

package main

import (
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"net/url"
)

type UUID struct {
	Uuid string `json:"uuid"`
}

func main() {
	apiURL := "https://httpbin.org/uuid"
	query := url.Values{}
	query.Add("q", "golang")
	query.Add("page", "1")
	ApiURL, _ := url.ParseRequestURI(apiURL)
	ApiURL.RawQuery = query.Encode()

	req, _ := http.NewRequest("GET", ApiURL.String(), nil)
	req.Header.Add("Accept", "*/*")

	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		return
	}
	defer resp.Body.Close()

	var uuid UUID
	body, err := io.ReadAll(resp.Body)
	if err != nil {
		fmt.Printf("read from resp.Body failed, err:%v\n", err)
		return
	}
	json.Unmarshal(body, &uuid)
	fmt.Println(uuid.Uuid)
}

POST 请求示例

package main

import (
	"encoding/json"
	"io"
	"net/http"
	"net/url"
)

type dockerToken struct {
	Token string `json:"token"`
}

func main() {

	apiUrl := "https://hub.docker.com/v2/users/login"
	data := url.Values{}
	data.Set("username", "username")
	data.Set("password", "password")
	resp, err := http.PostForm(apiUrl, data)
	if err != nil {
		return
	}
	defer resp.Body.Close()
	_data, _ := io.ReadAll(resp.Body)

	var tmpT dockerToken
	json.Unmarshal(_data, &tmpT)
}
package main

import (
	"bytes"
	"io"
	"net/http"
	"net/url"
	"strings"

	"log/slog"
)

func POST1() {
	apiURL := "https://httpbin.org/post"
	form := url.Values{}
	form.Add("ln", "ln222")
	form.Add("ip", "1.1.1.1")
	form.Add("ua", "ua123")

	client := &http.Client{}

	req, _ := http.NewRequest("POST", apiURL, strings.NewReader(form.Encode()))
	req.Header.Set("User-Agent", "test")
	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")

	// 发送请求
	resp, err := client.Do(req)
	if err != nil {
		slog.Error("POST request failed", "err", err)
		return
	}
	defer resp.Body.Close()

	// 读取内容
	body, err := io.ReadAll(resp.Body)
	if err != nil {
		slog.Error("POST request", "err", err)
	} else {
		slog.Info(string(body))
	}

}

func POSTJson() {
	apiURL := "https://httpbin.org/post"

	var jsonStr = []byte(`{"title":"this is a title", "cate": 1}`)

	client := &http.Client{}

	req, _ := http.NewRequest("POST", apiURL, bytes.NewBuffer(jsonStr))
	req.Header.Set("User-Agent", "test")
	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")

	// 发送请求
	resp, err := client.Do(req)
	if err != nil {
		slog.Error("POST request failed", "err", err)
		return
	}
	defer resp.Body.Close()

	// 读取内容
	body, err := io.ReadAll(resp.Body)
	if err != nil {
		slog.Error("POST request", "err", err)
	} else {
		slog.Info(string(body))
	}

}

func main() {
	// POST1()
	POSTJson()
}