0%

Go_发起网络请求模版(基于官方net库)

Go_发起网络请求模版(基于官方net库)

Go HTTP请求模板封装

1、导入包

package main

import (
"bytes"
"encoding/json"
"fmt"
"io"
"log"
"mime/multipart"
"net/http"
"net/url"
"os"
"strings"
)

1.1、GetRequest 发送GET请求

// GetRequest 发送GET请求
// url: 请求地址
// params: 查询参数(map格式)
// 返回: 响应体字节数组和错误信息
func GetRequest(url string, params map[string]string) ([]byte, error) {
// 1. 构建带参数的URL
query := url.Values{}
for k, v := range params {
query.Add(k, v)
}
fullURL := url
if len(params) > 0 {
fullURL += "?" + query.Encode()
}

// 2. 发送GET请求
resp, err := http.Get(fullURL)
if err != nil {
return nil, err
}
defer resp.Body.Close()

// 3. 读取响应体
return io.ReadAll(resp.Body)
}

参数说明:

  • url: 请求的目标地址(不包含查询参数),例如 "https://api.example.com/data"

  • params: 查询参数的键值对映射,例如:

    map[string]string{
    "page": "1",
    "limit": "20",
    }

    将生成?page=1&limit=20的查询字符串

1.2、PostJsonRequest 发送JSON格式的POST请求

// PostJsonRequest 发送JSON格式的POST请求
// url: 请求地址
// data: 要发送的JSON数据(任意结构体)
// 返回: 响应体字节数组和错误信息
func PostJsonRequest(url string, data interface{}) ([]byte, error) {
// 1. 序列化JSON数据
jsonData, err := json.Marshal(data)
if err != nil {
return nil, err
}

// 2. 创建请求
req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
if err != nil {
return nil, err
}
req.Header.Set("Content-Type", "application/json")

// 3. 发送请求并获取响应
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()

// 4. 读取响应体
return io.ReadAll(resp.Body)
}

参数说明:

  • url: 请求的目标地址,例如 "https://api.example.com/users"

  • data:任意可被JSON序列化的Go数据结构,例如:

    // 使用结构体
    struct {
    Name string `json:"name"`
    Email string `json:"email"`
    }{
    Name: "Alice",
    Email: "alice@example.com",
    }

    // 或使用map
    map[string]interface{}{
    "name": "Alice",
    "email": "alice@example.com",
    }

1.3、PostFormUrlEncodedRequest 发送x-www-form-urlencoded格式的POST请求

// PostFormUrlEncodedRequest 发送x-www-form-urlencoded格式的POST请求
// url: 请求地址
// formData: 表单数据(map格式)
// 返回: 响应体字节数组和错误信息
func PostFormUrlEncodedRequest(url string, formData map[string]string) ([]byte, error) {
// 1. 构建表单数据
data := url.Values{}
for k, v := range formData {
data.Set(k, v)
}

// 2. 发送请求
resp, err := http.Post(
url,
"application/x-www-form-urlencoded",
strings.NewReader(data.Encode()),
)
if err != nil {
return nil, err
}
defer resp.Body.Close()

// 3. 读取响应体
return io.ReadAll(resp.Body)
}

参数说明:

  • url: 请求的目标地址,例如 "https://api.example.com/login"

  • formData: 表单数据的键值对映射,例如:

    map[string]string{
    "username": "admin",
    "password": "myp@ssw0rd",
    }

1.4、PostFormDataRequest 发送multipart/form-data格式的POST请求(支持文件和文本混合)

// PostFormDataRequest 发送multipart/form-data格式的POST请求(支持文件和文本混合)
// url: 请求地址
// formData: 文本表单数据(map格式)
// fileField: 文件字段名
// filePath: 文件路径
// 返回: 响应体字节数组和错误信息
func PostFormDataRequest(url string, formData map[string]string, fileField, filePath string) ([]byte, error) {
// 1. 创建multipart写入器
body := &bytes.Buffer{}
writer := multipart.NewWriter(body)

// 2. 添加文本字段
for key, val := range formData {
_ = writer.WriteField(key, val)
}

// 3. 添加文件字段(如果提供了文件路径)
if filePath != "" {
file, err := os.Open(filePath)
if err != nil {
return nil, err
}
defer file.Close()

part, err := writer.CreateFormFile(fileField, file.Name())
if err != nil {
return nil, err
}
_, err = io.Copy(part, file)
if err != nil {
return nil, err
}
}

// 4. 关闭写入器(必须)
err := writer.Close()
if err != nil {
return nil, err
}

// 5. 创建请求
req, err := http.NewRequest("POST", url, body)
if err != nil {
return nil, err
}
req.Header.Set("Content-Type", writer.FormDataContentType())

// 6. 发送请求
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()

// 7. 读取响应
return io.ReadAll(resp.Body)
}

参数说明:

  • url: 请求的目标地址,例如 "https://api.example.com/upload"

  • formData: 文本字段的键值对映射,例如:

    map[string]string{
    "description": "用户头像",
    "category": "profile",
    }
  • fileField: 服务器用于接收文件的字段名称(表单域名称),例如 "avatar"

  • filePath: 要上传的文件在本地系统的完整路径,例如 "/tmp/photo.jpg"

特殊说明filePath 参数为空字符串 "" 时,表示不上传文件,只发送文本表单数据

2、请求示例:

// ============================
// 使用示例
// ============================
func main() {
// 示例1: GET请求
getResp, err := GetRequest("https://httpbin.org/get", map[string]string{
"param1": "value1",
"param2": "value2",
})
if err != nil {
log.Fatal("GET请求失败:", err)
}
fmt.Println("GET响应:\n", string(getResp))

// 示例2: POST JSON请求
jsonResp, err := PostJsonRequest("https://httpbin.org/post", map[string]interface{}{
"name": "Alice",
"email": "alice@example.com",
})
if err != nil {
log.Fatal("JSON POST失败:", err)
}
fmt.Println("JSON POST响应:\n", string(jsonResp))

// 示例3: Form-urlencoded请求
formResp, err := PostFormUrlEncodedRequest("https://httpbin.org/post", map[string]string{
"username": "bob",
"password": "secret",
})
if err != nil {
log.Fatal("Form-urlencoded POST失败:", err)
}
fmt.Println("Form-urlencoded响应:\n", string(formResp))

// 示例4: Form-data请求(含文件)
// formDataResp, err := PostFormDataRequest(
// "https://httpbin.org/post",
// map[string]string{"textField": "textValue"},
// "fileField",
// "./test.txt", // 实际文件路径
// )
// if err != nil {
// log.Fatal("Form-data POST失败:", err)
// }
// fmt.Println("Form-data响应:\n", string(formDataResp))
}

通用返回说明

所有函数均返回两个值:

  1. []byte: 原始响应体内容,需要调用方自行解析(如使用 json.Unmarshal()
  2. error: 错误对象,请求成功时返回 nil,失败时包含错误详情
// 典型使用示例
respBytes, err := GetRequest("https://api.example.com/data", params)
if err != nil {
// 处理错误
log.Fatal("请求失败:", err)
}

// 解析JSON响应
var result ResponseStruct
if err := json.Unmarshal(respBytes, &result); err != nil {
// 处理解析错误
}