通过form-data上传文件后,后台service从哪里可以获取其文件名?

通过form-data上传文件后,后台service从哪里可以获取其文件名?

  • 背景
  • 开始探索
  • 验证阶段
  • 参考

背景

之前都是做桌面软件和嵌入式软件开发的。最近刚入门后端开发,对很多后端的知识不太了解。项目中有这样一个需求,需要向后端发送一组信息,其中包括文件资料,如图片。其他都是这些资料的元数据信息。如下图所示。请求发送后,后端service怎样从请求中获知文件名信息?

当然,我可以在发送情况的时候,在元数据里添加文件名字段,这也是一个办法。但从http请求中能否获得呢?我们一起来看看。
通过form-data上传文件后,后台service从哪里可以获取其文件名?_第1张图片

开始探索

经同事指引,了解到HTTP header中有 Content-Dispostion字段,它就是用来放置这些信息的。
在参考1中有详细的介绍。

Content-Disposition: form-data
Content-Disposition: form-data; name="fieldName"
Content-Disposition: form-data; name="fieldName"; filename="filename.jpg"

资料阅读过后,心中就有了答案了。上传的文件名必定藏在http请求中。经过研究请求的源码,发现在golang的HTTP Request中有下面这样的字段。

PostForm url.Values

    // MultipartForm is the parsed multipart form, including file uploads.
    // This field is only available after ParseMultipartForm is called.
    // The HTTP client ignores MultipartForm and uses Body instead.
    MultipartForm *multipart.Form

而Form字段的定义是:

type Form struct {
    Value map[string][]string
    File  map[string][]*FileHeader
}

其中发现有一个指向FileHeader类型的指针数组,FileHeader看上去有点意思,里面有没有我们想要的信息呢?继续往下看。

// A FileHeader describes a file part of a multipart request.
type FileHeader struct {
	Filename string
	Header   textproto.MIMEHeader
	Size     int64

	content []byte
	tmpfile string
}

果然,里面有Filename字段。而Filename正是我们想要的信息。那如何去获取呢?File是一个map表,它的值是一个指向FileHeader类型的指针数组,我们需要根据我们先遍历map,从map中取出一个指针数组,然后去遍历这个指针数组。
思路有了,那接下来就是验证的时刻了。

验证阶段

根据上面的思路,我们先写如下代码,从map中取出key(icon)对于的value,看看value内存的是什么。

fileMap := params.HTTPRequest.MultipartForm.File
for k, v := range fileMap {
	fmt.Printf("key:%s, value:%s", k, v)
}

得到的结果如下:

key:icon, value:[%!s(*multipart.FileHeader=&{QQ音乐.png map[Content-Disposition:[form-data; name="icon"; filename="QQ音乐.png"] Content-Type:[image/png]] 

有点意思了,从这个输出结果中,我们看到了前面说的Content-Disposition信息了,其中就有filename。这没让我失望。
继续遍历指针数组:

for _, files := range fileMap {
	for _, file := range files {
		fmt.Printf("filename:%s", file.Filename)
	}
}

log输出结果如下,果然没让我们失望。

filename:QQ音乐.png

至此,问题完美解决!

参考

  1. Content-Disposition介绍
  2. go/src/net/http/request.go
  3. go/src/mime/multipart/formdata.go

你可能感兴趣的:(Go)