【五、http】go的http的信息提交(表单,json,上传文件)

一、post提交的几种

  • form表单
  • json
  • 文件

1、提交表单

cpp 复制代码
//http的post

func requstPost(){
	params := make(url.Values)
	params.Set("name", "kaiyue")
	params.Set("age", "18")

	formDataStr := []byte(params.Encode())
	formDataByte := bytes.NewBuffer(formDataStr)

	requst, err := http.NewRequest(http.MethodPost, "http://httpbin.org/post", formDataByte)
	if err != nil {
		fmt.Println("ss")
	}
	requst.URL.RawQuery = params.Encode()

	r, err := http.DefaultClient.Do(requst)
	if err != nil {
		fmt.Println("ss")
	}
	defer r.Body.Close()
	printBody(r)
}

2、提交json

cpp 复制代码
func postJson(){
	u := struct {
		Name string `json:"name"`
		Age int `json:"age"`
	}{
		Name: "kaiyue",
		Age: 18,
	}
	payload, _ := json.Marshal(u)
	r, _ := http.Post(
		"http://httpbin.org/post",
		"application/x-www-form-urlencoded",
		bytes.NewReader(payload),
	)
	defer r.Body.Close()

	content, _ := io.ReadAll(r.Body)
	fmt.Printf("%s\n", content)
}

func main() {
	postJson()
}

结果:

cpp 复制代码
{
  "args": {}, 
  "data": "", 
  "files": {}, 
  "form": {
    "{\"name\":\"kaiyue\",\"age\":18}": ""
  }, 
  "headers": {
    "Accept-Encoding": "gzip", 
    "Content-Length": "26", 
    "Content-Type": "application/x-www-form-urlencoded", 
    "Host": "httpbin.org", 
    "User-Agent": "Go-http-client/1.1", 
    "X-Amzn-Trace-Id": "Root=1-6544fb3a-777a0c6563dee4ad74037aeb"
  }, 
  "json": null, 
  "origin": "120.244.60.192", 
  "url": "http://httpbin.org/post"
}

3、提交文件

cpp 复制代码
package main

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

func postForm() {
	// form data 形式 query string,类似于 name=poloxue&age=18
	data := make(url.Values)
	data.Add("name", "poloxue")
	data.Add("age", "18")
	payload := data.Encode()

	r, _ := http.Post(
		"http://httpbin.org/post",
		"application/x-www-form-urlencoded",
		strings.NewReader(payload),
	)
	defer func() { _ = r.Body.Close() }()

	content, _ := ioutil.ReadAll(r.Body)
	fmt.Printf("%s", content)
}

func postJson() {
	u := struct {
		Name string `json:"name"`
		Age  int    `json:"age"`
	}{
		Name: "poloxue",
		Age:  18,
	}
	payload, _ := json.Marshal(u)
	r, _ := http.Post(
		"http://httpbin.org/post",
		"application/json",
		bytes.NewReader(payload),
	)
	defer func() { _ = r.Body.Close() }()

	content, _ := ioutil.ReadAll(r.Body)
	fmt.Printf("%s", content)
}

func postFile() {
	body := &bytes.Buffer{}

	writer := multipart.NewWriter(body)
	_ = writer.WriteField("words", "123")

	// 一个是输入表单的 name,一个上传的文件名称
	upload1Writer, _ := writer.CreateFormFile("uploadfile1", "uploadfile1")

	uploadFile1, _ := os.Open("uploadfile1")
	defer func() {_ = uploadFile1.Close()}()

	_, _ = io.Copy(upload1Writer, uploadFile1)

	// 一个是输入表单的 name,一个上传的文件名称
	upload2Writer, _ := writer.CreateFormFile("uploadfile2", "uploadfile2")

	uploadFile2, _ := os.Open("uploadfile2")
	defer func() {_ = uploadFile2.Close()}()

	_, _ = io.Copy(upload2Writer, uploadFile2)

	_ = writer.Close()

	fmt.Println(writer.FormDataContentType())
	fmt.Println(body.String())
	r, _ := http.Post("http://httpbin.org/post",
		writer.FormDataContentType(),
		body,
	)
	defer func() {_ = r.Body.Close()}()

	content, _ := ioutil.ReadAll(r.Body)

	fmt.Printf("%s", content)
}

func main() {
	// post 请求的本质,它是 request body 提交,相对于 get 请求(urlencoded 提交查询参数, 提交内容有大小限制,好像 2kb)
	// post 不同的形式也就是 body 的格式不同
	// post form 表单,body 就是 urlencoded 的形式,比如 name=poloxue&age=18
	// post json,提交的 json 格式
	// post 文件,其实也是组织 body 数据
	// postJson()
	postFile()
}

其中

uploadfile1 中的内容为 abc

uploadfile2 中的内容为 abc

结果:

cpp 复制代码
multipart/form-data; boundary=a7c095e326382b46f363a6fa2d579ea3c02245a6a8368969a37ddfb50dd2
--a7c095e326382b46f363a6fa2d579ea3c02245a6a8368969a37ddfb50dd2
Content-Disposition: form-data; name="words"

123
--a7c095e326382b46f363a6fa2d579ea3c02245a6a8368969a37ddfb50dd2
Content-Disposition: form-data; name="uploadfile1"; filename="uploadfile1"
Content-Type: application/octet-stream

abc

--a7c095e326382b46f363a6fa2d579ea3c02245a6a8368969a37ddfb50dd2
Content-Disposition: form-data; name="uploadfile2"; filename="uploadfile2"
Content-Type: application/octet-stream

abc

--a7c095e326382b46f363a6fa2d579ea3c02245a6a8368969a37ddfb50dd2--

{
  "args": {}, 
  "data": "", 
  "files": {
    "uploadfile1": "abc\n", 
    "uploadfile2": "abc\n"
  }, 
  "form": {
    "words": "123"
  }, 
  "headers": {
    "Accept-Encoding": "gzip", 
    "Content-Length": "559", 
    "Content-Type": "multipart/form-data; boundary=a7c095e326382b46f363a6fa2d579ea3c02245a6a8368969a37ddfb50dd2", 
    "Host": "httpbin.org", 
    "User-Agent": "Go-http-client/1.1", 
    "X-Amzn-Trace-Id": "Root=1-6544fc1a-3104d8a606a4510d6a68fcde"
  }, 
  "json": null, 
  "origin": "120.244.60.192", 
  "url": "http://httpbin.org/post"
}
相关推荐
壹方秘境9 分钟前
ChatTCP是怎么像Wireshark那样识别TCP重传、乱序和心跳保活的
网络协议·tcp/ip·wireshark
张忠琳2 小时前
【Go 1.26.4】Golang Select 深度解析
开发语言·后端·golang
提笔了无痕3 小时前
如何用Go实现整套RAG流程
开发语言·后端·golang
wlsh154 小时前
Go 错误处理
golang
geovindu4 小时前
go: Generators Pattern
开发语言·后端·设计模式·golang·生成器模式
27669582926 小时前
泡泡玛特app 腾讯企业加固/支付宝加固脱修frida rpc调用
网络·网络协议·rpc·frida·泡泡玛特·ppmt·泡泡玛特app-rpc调用
未来侦察班8 小时前
网络协议 网络层,万物归于IP
网络·网络协议·协议·ip·网络层·tcpip
colofullove9 小时前
实时游玩页与 WebSocket 状态管理实现
websocket·网络协议·状态模式
小短腿的代码世界9 小时前
WebSocket协议在Qt中的工业级实现:5层架构设计与万级并发压测验证
qt·websocket·网络协议
青春喂了后端9 小时前
Go Sidecar Status 性能优化
开发语言·性能优化·golang