Golang如何接收客户端的multipart数据

Golang如何接收客户端的multipart数据 以下是我的代码和输出:

func RestClient(req *http.Request) {
		fmt.Println("main (120):::", req.MultipartForm.File)
}
main (120)::: &{map[userName:[0xc4200a66e0] diamond:[0xc4200f67b0] ]}
for k,v := range req.MultipartForm.File{
		if k == "userName" {
			for _, v2 := range v {
				fmt.Println("main (130):::",v2)
			}
		}
	}
main (130)::: &{ map[Content-Length:[8] Content-Disposition:[form-data; name="dk"] Content-Transfer-Encoding:[binary] Content-Type:[multipart/form-data; charset=utf-8]] 8 [117 115 101 114 78 97 109 101] }

我想要获取(字节切片 [117 115 101 114 78 97 109 101])但无法提取出来,如何打印(内容字节)。正如我们所知,这是来自FileHeader结构体的字段:

type FileHeader struct {
	Filename string
	Header   textproto.MIMEHeader
	Size     int64

	content []byte
	tmpfile string
}

提前感谢。


更多关于Golang如何接收客户端的multipart数据的实战教程也可以访问 https://www.itying.com/category-94-b0.html

4 回复

感谢您的帮助。 最终,我解决了这个问题:

for k,v := range req.MultipartForm.File{
		if k == "userName" {
			for _, v2 := range v {
				fmt.Println("main (130):::",v2)
	               b,_:=v2.Open()
					 sliceByte,_:=ioutil.ReadAll(b)
					   fmt.Println("main (245):::",string(sliceByte))
			}
		}
	}

更多关于Golang如何接收客户端的multipart数据的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


当你在拥有 FileHeader 的包中时,可以使用点符号访问字段,例如 fh.content;如果你不是该结构体的所有者,则无法访问该字段,需要查看所属包的文档以了解是否有提取字段值的函数或方法。

PS:如果你指的是 multipart.FileHeader,我粗略看了一下没有找到访问该字段的方法,不过我没有深入研究代码,也许可以通过 Open() 方法实现?

fh.content
multipart.FileHeader
Open()

好的,我查看了 Open() 的代码:

https://golang.org/src/mime/multipart/formdata.go?s=3582:3791#L140

func (fh *FileHeader) Open() (File, error) {
	if b := fh.content; b != nil {
		r := io.NewSectionReader(bytes.NewReader(b), 0, int64(len(b)))
		return sectionReadCloser{r}, nil
	}
	return os.Open(fh.tmpfile)
}

如你所见,如果存在非 nil 的内容,你可以在打开 FileHeader 后从返回的 File 中读取它。不过从你的代码中无法知道 FileHeader.content 中是否有内容,或者你是否从磁盘获取了一个文件,因为这些信息被抽象掉了。

请记住:以小写字母开头的标识符不会从包中导出,因此不能在"外部"使用。

要访问 multipart.FileHeader 中的内容字节,你需要打开文件并读取其内容。FileHeader 中的 content 字段是未导出的,不能直接访问。以下是正确的方法:

func RestClient(req *http.Request) {
    // 解析 multipart 表单数据
    err := req.ParseMultipartForm(32 << 20) // 32MB 最大内存
    if err != nil {
        fmt.Println("解析错误:", err)
        return
    }

    // 遍历文件字段
    for k, v := range req.MultipartForm.File {
        if k == "userName" {
            for _, fileHeader := range v {
                // 打开文件
                file, err := fileHeader.Open()
                if err != nil {
                    fmt.Println("文件打开错误:", err)
                    continue
                }
                defer file.Close()

                // 读取文件内容
                content, err := io.ReadAll(file)
                if err != nil {
                    fmt.Println("读取错误:", err)
                    continue
                }

                fmt.Printf("字段 %s 的内容: %s\n", k, string(content))
                fmt.Printf("字段 %s 的字节: %v\n", k, content)
            }
        }
    }
}

输出示例:

字段 userName 的内容: userName
字段 userName 的字节: [117 115 101 114 78 97 109 101]

关键点:

  1. 必须先调用 req.ParseMultipartForm() 来解析 multipart 数据
  2. 使用 fileHeader.Open() 获取文件对象
  3. 使用 io.ReadAll() 读取文件内容到字节切片

如果你需要处理多个字段,可以这样遍历:

for fieldName, fileHeaders := range req.MultipartForm.File {
    for _, fileHeader := range fileHeaders {
        file, err := fileHeader.Open()
        if err != nil {
            continue
        }
        defer file.Close()
        
        content, err := io.ReadAll(file)
        if err != nil {
            continue
        }
        
        fmt.Printf("字段 %s: %s\n", fieldName, string(content))
    }
}
回到顶部