golang解析http multipart/form的三种方式

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了golang解析http multipart/form的三种方式相关的知识,希望对你有一定的参考价值。

multipart/form-data 顾名思义可以上传多个form-data 并且用分隔符进行分割,多用于文件上传

1. http  multipart/form-data 请求样例

POST /handle HTTP/1.1 

Host: localhost:8080 

Connection: keep-alive 

Content-Length: 182537 

Cache-Control: max-age=0 

Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryWdDAe6hxfa4nl2Ig

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8 

Accept-Encoding: gzip, deflate, br 

Accept-Language: zh-CN,zh;q=0.9


------WebKitFormBoundaryWdDAe6hxfa4nl2Ig

Content-Disposition: form-data; name="submit-name"

jack

------WebKitFormBoundaryWdDAe6hxfa4nl2Ig

Content-Disposition: form-data; name="file1"; filename="out.png"

Content-Type: image/png

binary-data

------WebKitFormBoundaryWdDAe6hxfa4nl2Ig

Content-Disposition: form-data; name="file2"; filename="2.png"

Content-Type: image/png

binary-data-2

------WebKitFormBoundaryWdDAe6hxfa4nl2Ig--


2. golang解析示例


package main


import (

"bytes"

"net/http"

"io/ioutil"

"fmt"

"mime/multipart"

"io"

)


func main() {


bodyBuf := bytes.NewBuffer(nil)

bodyBuf.WriteString(`------WebKitFormBoundaryWdDAe6hxfa4nl2Ig

Content-Disposition: form-data; name="submit-name"


xiongwei

------WebKitFormBoundaryWdDAe6hxfa4nl2Ig

Content-Disposition: form-data; name="file1"; filename="out.png"

Content-Type: image/png


binary-data

------WebKitFormBoundaryWdDAe6hxfa4nl2Ig

Content-Disposition: form-data; name="file2"; filename="2.png"

Content-Type: image/png


binary-data-2

------WebKitFormBoundaryWdDAe6hxfa4nl2Ig--`)

req := &http.Request{

Method: "POST",

Header: http.Header{"Content-Type": {`multipart/form-data; boundary=----WebKitFormBoundaryWdDAe6hxfa4nl2Ig`}},

Body:   ioutil.NopCloser(bodyBuf),

}


getMultiPart3(req)

}


//通过r.ParseMultipartForm

func getMultiPart1(r *http.Request)  {

/**

底层通过调用multipartReader.ReadForm来解析

如果文件大小超过maxMemory,则使用临时文件来存储multipart/form中文件数据

*/

r.ParseMultipartForm(128)

fmt.Println("r.Form:         ",r.Form)

fmt.Println("r.PostForm:     ",r.PostForm)

fmt.Println("r.MultiPartForm:",r.MultipartForm)

getFormData(r.MultipartForm)


}


//通过MultipartReader

func getMultiPart2(r *http.Request)()  {


mr,err := r.MultipartReader()

if err != nil{

fmt.Println("r.MultipartReader() err,",err)

return

}

form ,_ := mr.ReadForm(128)

getFormData(form)

}



//字节解析multi-part

func getMultiPart3(r *http.Request)()  {


mr,err := r.MultipartReader()

if err != nil{

fmt.Println("r.MultipartReader() err,",err)

return

}

for{

p ,err := mr.NextPart()

if err == io.EOF{

break

}

if err != nil{

fmt.Println("mr.NextPart() err,",err)

break

}

fmt.Println("part header:",p.Header)

formName := p.FormName()

fileName := p.FileName()

if formName != "" && fileName == ""{

formValue,_:= ioutil.ReadAll(p)

fmt.Printf("formName:%s,formValue:%s ",formName,formValue)

}

if fileName != "" {

fileData,_:=ioutil.ReadAll(p)

fmt.Printf("fileName:%s,fileData:%s ",fileName,fileData)

}

fmt.Println()

}

}



func getFormData(form *multipart.Form)  {

//获取 multi-part/form body中的form value

for k,v := range form.Value{

fmt.Println("value,k,v = ",k,",",v)

}

fmt.Println()

//获取 multi-part/form中的文件数据

for _,v := range form.File {

for i:=0 ;i < len(v);i++{

fmt.Println("file part ",i,"-->")

fmt.Println("fileName   :",v[i].Filename)

fmt.Println("part-header:",v[i].Header)

f,_ := v[i].Open()

buf,_:= ioutil.ReadAll(f)

fmt.Println("file-content",string(buf))

fmt.Println()

}

}

}

技术分享图片

以上是关于golang解析http multipart/form的三种方式的主要内容,如果未能解决你的问题,请参考以下文章

Golang里实现Http服务器并解析header参数和表单参数

golang解析http multipart/form的三种方式

golang基础-http请求的几种方式

golang基础-http请求的几种方式

golang-gin框架参数解析

Golang net/http 爬虫[1]