golang原生http包实现各种情况的post请求

go实现各种类型的post请求

请求测试地址

var (
	requestPostURL    string = "http://httpbin.org/post"
	// 接收文件的服务自己实现qwq
	// 接收一张图片上传 postman的key file
	imagePostURL      string = "/imageUpload/upload"
	// 接收多张图片上传 postman的key file
	imageMultiPostURL string = "/imageUpload/uploads"
)

application/x-www-from-urlencoded

  • 说明
application/x-www-from-urlencoded,会将表单内的数据转换为键值对,比如,name=java&age = 23
  • 示例
// 
func postXWwwFromURLEncoded() {
	client := http.Client{}
	// 不带任何的请求数据post
	// req, err := http.NewRequest(http.MethodPost, requestPostURL, nil)

	// 带数据
	urlValues := url.Values{}
	urlValues.Add("name", "张三")
	urlValues.Add("age", "18")
	reqBody := urlValues.Encode()
	req, err := http.NewRequest(http.MethodPost, requestPostURL, strings.NewReader(reqBody))
	if err != nil {
		log.Println("err")
	}
	resp, err := client.Do(req)
	if err != nil {
		log.Println("err")
	}
	defer resp.Body.Close()

	b, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		log.Println("err")
	}
	fmt.Println(string(b))
	// urlValues := url.Values{}
	// urlValues.Add("name","zhaofan")
	// urlValues.Add("age","22")
	// resp, _ := http.PostForm("http://httpbin.org/post",urlValues)

}

raw

  • 说明
// 也就是入参方式为json
// 可以上传任意格式的文本,可以上传text、json、xml、html
  • 示例
func postRaw() {
	client := http.Client{}
	// 带数据 json 类型
	urlValues := map[string]interface{}{
		"name":      "jack",
		"age":       18,
		"is_active": true,
	}

	b1, _ := json.Marshal(&urlValues)
	// b1, _ := json.Marshal(&urlValues)

	req, err := http.NewRequest(http.MethodPost, requestPostURL, bytes.NewReader(b1))
	if err != nil {
		log.Println("err")
	}
	resp, err := client.Do(req)
	if err != nil {
		log.Println("err")
	}
	defer resp.Body.Close()

	b, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		log.Println("err")
	}
	fmt.Println(string(b))
}

multipart/form-data 带普通参数

  • 说明

// multipart/form-data
// 既可以上传文件,也可以上传键值对
// 上传的字段是文件时,会有Content-Type来说明文件类型;content-disposition
// 可以上传多个文件

  • 示例
//  multipart/form-data 带普通参数 key-value
func postFormDataWithParams() {
	client := http.Client{}
	// 不带任何的请求数据post
	body := &bytes.Buffer{}
	writer := multipart.NewWriter(body)
	params := map[string]string{
		"name": "zhangsan",
		"age":  "12",
	}
	for key, val := range params {
		_ = writer.WriteField(key, val)
	}
	writer.Close()
	req, err := http.NewRequest(http.MethodPost, requestPostURL, body)
	if err != nil {
		log.Println("err")
	}
	resp, err := client.Do(req)
	if err != nil {
		log.Println("err")
	}
	defer resp.Body.Close()

	b, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		log.Println("err")
	}
	fmt.Println(string(b))
}

multipart/form-data 上传一个文件

//  key:file  里面放一个文件
//  multipart/form-data 传一个文件
func postFormDataWithSingleFile() {
	client := http.Client{}
	bodyBuf := &bytes.Buffer{}
	bodyWrite := multipart.NewWriter(bodyBuf)

	file, err := os.Open("./images/img.jpg")
	defer file.Close()
	if err != nil {
		log.Println("err")
	}
	// file 为key
	fileWrite, err := bodyWrite.CreateFormFile("file", "img.jpg")
	_, err = io.Copy(fileWrite, file)
	if err != nil {
		log.Println("err")
	}

	bodyWrite.Close() //要关闭,会将w.w.boundary刷写到w.writer中

	// 创建请求
	contentType := bodyWrite.FormDataContentType()
	req, err := http.NewRequest(http.MethodPost, imagePostURL, bodyBuf)
	if err != nil {
		log.Println("err")
	}
	// 设置头
	req.Header.Set("Content-Type", contentType)

	resp, err := client.Do(req)
	if err != nil {
		log.Println("err")
	}
	defer resp.Body.Close()

	b, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		log.Println("err")
	}
	fmt.Println(string(b))
}

multipart/form-data 上传多个文件

// key:file 里面放多个文件
//  multipart/form-data 传多个文件
func postFormDataWithMultipartFile() {
	client := http.Client{}
	bodyBuf := &bytes.Buffer{}
	bodyWrite := multipart.NewWriter(bodyBuf)

	images := []string{"img.jpg", "img1.jpg"}
	for _, val := range images {
		file, err := os.Open("./images/" + val)
		defer file.Close()
		if err != nil {
			log.Println("err")
		}

		fileWrite, err := bodyWrite.CreateFormFile("file", val)
		_, err = io.Copy(fileWrite, file)
		if err != nil {
			log.Println("err")
		}
	}
	bodyWrite.Close() //要关闭,会将w.w.boundary刷写到w.writer中

	// 创建请求
	req, err := http.NewRequest(http.MethodPost, imagePostURL, bodyBuf)
	if err != nil {
		log.Println("err")
	}
	// 设置头
	contentType := bodyWrite.FormDataContentType()
	req.Header.Set("Content-Type", contentType)

	resp, err := client.Do(req)
	if err != nil {
		log.Println("err")
	}
	defer resp.Body.Close()

	b, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		log.Println("err")
	}
	fmt.Println(string(b))
}

binary

// Content-Type:application/octet-stream,从字面意思得知,只可以上传二进制数据,通常用来上传文件,
// 由于没有键值,所以,一次只能上传一个文件
func postBinary() {

}