HTTP-POST文件多部分

huangapple go评论86阅读模式
英文:

HTTP-POST file multipart

问题

我正在尝试使用Go的mime/multipart和http包发送一个多部分表单,并且我需要一些帮助来解决它。

HTML代码如下:


<html>
<head><title>Multipart Test</title></head>
<body>
<form action="/multipart" enctype="multipart/form-data" method="POST">

<label for="file"> 请选择一个文件 </label>
<input id="file" type="file" name="file"/>
<br>
<label for="input1"> 请输入一些文本 </label>
<input id="input1" type="text" name="input1"/>
<br>
<label for="input2"> 请输入更多文本 </label>
<input id="input2" type="text" name="input2"/>
<br>
<input type="submit" name="Submit" value="Submit"/>
</body>
</html>

我的Go代码如下:


var buffer bytes.Buffer
w := multipart.NewWriter(&buffer)
// 写入字段和文件
w.CreateFormField("input1")
w.WriteField("input1","value1")
w.CreateFormFile("file","filename.dat")
// 我需要一个Reader来读取文件,但是怎么做呢?
// 然后发送请求
resp,err := http.Post(url,w.FormDataContentType(),&buffer)

英文:

I'm trying to send a multipart form using Go packages mime/multipart and http, and I need some help to solve it.

The HTML would be:


<html>
<head><title>Multipart Test</title></head>
<body>
<form action="/multipart" enctype="multipart/form-data" method="POST">

<label for="file"> Please select a File </label>
<input id="file" type="file" name="file"/>
<br>
<label for="input1"> Please write some text </label>
<input id="input1" type="text" name="input1"/>
<br>
<label for="input2"> Please write some more text </label>
<input id="input2" type="text" name="input2"/>
<br>
<input type="submit" name="Submit" value="Submit"/>
</body>
</html>

And my Go approach is like this:


var buffer bytes.Buffer
w := multipart.NewWriter(&buffer)
// Write fields and files
w.CreateFormField("input1")
w.WriteField("input1","value1")
w.CreateFormFile("file","filename.dat")
// I need a Reader to here to read the file, but how ?
// then send the request
resp,err := http.Post(url,w.FormDataContentType(),&buffer)

答案1

得分: 10

// 上传文件到谷歌代码
func Upload(tarball string) (err os.Error) {
// 创建缓冲区
buf := new(bytes.Buffer) // 注意,我认为不要在大文件上使用这个,
// 创建一个临时文件并从那里组装你的多部分(未经测试)
w := multipart.NewWriter(buf)
// 为字段标签创建一个表单字段写入器
label, err := w.CreateFormField("label")
if err != nil {
return err
}
// 写入标签字段
label.Write([]byte("这里是标签"))
// 为字段摘要创建一个表单字段写入器
summary, err := w.CreateFormField("summary")
if err != nil {
return err
}
// 写入摘要字段
summary.Write([]byte("这里是摘要"))
// 创建文件字段
fw, err := w.CreateFormFile("upload", tarball)
if err != nil {
return err
}
fd, err := os.Open(tarball)
if err != nil {
return err
}
defer fd.Close()
// 从文件中将文件字段写入上传
_, err = io.Copy(fw, fd)
if err != nil {
return err
}
// 如果您不关闭多部分写入器,您将没有一个终止边界
w.Close()
req, err := http.NewRequest("POST", repoUrl, buf)
if err != nil {
return err
}
req.Header.Set("Content-Type", w.FormDataContentType())
req.SetBasicAuth("email@email.com", "password")
res, err := client.Do(req)
if err != nil {
return err
}
io.Copy(os.Stderr, res.Body) // 用状态码检查替换这个
return err
}

英文:

The answer can be found following this sample code

// Upload file to google code
func Upload(tarball string) (err os.Error) {
	// Create buffer
	buf := new(bytes.Buffer) // caveat IMO dont use this for large files, \
	// create a tmpfile and assemble your multipart from there (not tested) 
	w := multipart.NewWriter(buf)
	// Create a form field writer for field label
	label, err := w.CreateFormField("label")
	if err != nil {
		return err
	}
	// Write label field
	label.Write([]byte("label here"))
	// Create a form field writer for field summary
	summary, err := w.CreateFormField("summary")
	if err != nil {
		return err
	}
	// Write summary field
	summary.Write([]byte("summary here"))
	// Create file field
	fw, err := w.CreateFormFile("upload", tarball)
	if err != nil {
		return err
	}
	fd, err := os.Open(tarball)
	if err != nil {
		return err
	}
	defer fd.Close()
	// Write file field from file to upload
	_, err = io.Copy(fw, fd)
	if err != nil {
		return err
	}
	// Important if you do not close the multipart writer you will not have a 
	// terminating boundry 
	w.Close()
	req, err := http.NewRequest("POST", repoUrl, buf)
	if err != nil {
		return err
	}
	req.Header.Set("Content-Type", w.FormDataContentType())
	req.SetBasicAuth("email@email.com", "password")
	res, err := client.Do(req) 
	if err != nil {
		return err
	}
	io.Copy(os.Stderr, res.Body) // Replace this with Status.Code check
	return err
}

huangapple
  • 本文由 发表于 2011年8月29日 04:14:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/7223616.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定