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

暮色伊人 · · 18787 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

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\n",formName,formValue)

}

if fileName != "" {

fileData,_:=ioutil.ReadAll(p)

fmt.Printf("fileName:%s,fileData:%s\n",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()

}

}

}

image.png


有疑问加站长微信联系(非本文作者)

本文来自:51CTO博客

感谢作者:暮色伊人

查看原文:golang解析http multipart/form的三种方式

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

18787 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传