英文:
Go - accepting http post multipart file(s)
问题
我正在尝试弄清楚如何在Go中接受/接收HTTP Post请求。我只想能够接收一个文件,获取其MIME类型并将文件保存在本地。
我已经搜索了一整天,但我只能找到如何将文件发送到某个远程位置的示例,没有一个示例涵盖接收文件的情况。
任何帮助将不胜感激。
使用Justinas的示例并结合我的现有实验,我已经做到了这一点,但是m.Post似乎从未被调用。
package main
import (
"fmt"
"io"
"net/http"
"os"
"github.com/codegangsta/martini"
"github.com/codegangsta/martini-contrib/render"
)
func main() {
m := martini.Classic()
m.Use(render.Renderer(render.Options{
Directory: "templates", // 指定要加载模板的路径。
Layout: "layout", // 指定布局模板。布局模板可以调用{{ yield }}来渲染当前模板。
Charset: "UTF-8", // 设置json和html内容类型的编码。
}))
m.Get("/", func(r render.Render) {
fmt.Printf("%v\n", "g./")
r.HTML(200, "hello", "world")
})
m.Get("/:who", func(args martini.Params, r render.Render) {
fmt.Printf("%v\n", "g./:who")
r.HTML(200, "hello", args["who"])
})
m.Post("/up", func(w http.ResponseWriter, r *http.Request) {
fmt.Printf("%v\n", "p./up")
file, header, err := r.FormFile("file")
defer file.Close()
if err != nil {
fmt.Fprintln(w, err)
return
}
out, err := os.Create("/tmp/file")
if err != nil {
fmt.Fprintf(w, "Failed to open the file for writing")
return
}
defer out.Close()
_, err = io.Copy(out, file)
if err != nil {
fmt.Fprintln(w, err)
}
// 头部包含有用的信息,如原始文件名
fmt.Fprintf(w, "文件 %s 上传成功。", header.Filename)
})
m.Run()
}
以上是你提供的代码的翻译。
英文:
I am trying to figure out how to accept/receive a HTTP Post in Go. I just want to be able to receive a file, grab its mime-type and save the file locally.
I've been searching all day but all I can find is how to send a file to some remote location but none of the examples I find cover receiving it.
Any help would be appreciated.
using Justinas' example and mixing with my existing experiment I've gotten this far but m.Post never seems to be called.
package main
import (
"fmt"
"io"
"net/http"
"os"
"github.com/codegangsta/martini"
"github.com/codegangsta/martini-contrib/render"
)
func main() {
m := martini.Classic()
m.Use(render.Renderer(render.Options{
Directory: "templates", // Specify what path to load the templates from.
Layout: "layout", // Specify a layout template. Layouts can call {{ yield }} to render the current template.
Charset: "UTF-8", // Sets encoding for json and html content-types.
}))
m.Get("/", func(r render.Render) {
fmt.Printf("%v\n", "g./")
r.HTML(200, "hello", "world")
})
m.Get("/:who", func(args martini.Params, r render.Render) {
fmt.Printf("%v\n", "g./:who")
r.HTML(200, "hello", args["who"])
})
m.Post("/up", func(w http.ResponseWriter, r *http.Request) {
fmt.Printf("%v\n", "p./up")
file, header, err := r.FormFile("file")
defer file.Close()
if err != nil {
fmt.Fprintln(w, err)
return
}
out, err := os.Create("/tmp/file")
if err != nil {
fmt.Fprintf(w, "Failed to open the file for writing")
return
}
defer out.Close()
_, err = io.Copy(out, file)
if err != nil {
fmt.Fprintln(w, err)
}
// the header contains useful info, like the original file name
fmt.Fprintf(w, "File %s uploaded successfully.", header.Filename)
})
m.Run()
}
答案1
得分: 9
Go的net/http
服务器处理这个问题非常简单,它在幕后使用mime/multipart
包。你只需要在你的*http.Request
上调用r.FormFile()
,就可以得到一个multipart.File。
这里有一个完整的示例。使用curl上传文件的结果如下:
justinas@ubuntu /tmp curl -i -F file=@/tmp/stuff.txt http://127.0.0.1:8080/
HTTP/1.1 100 Continue
HTTP/1.1 200 OK
Date: Tue, 24 Dec 2013 20:56:07 GMT
Content-Length: 37
Content-Type: text/plain; charset=utf-8
文件 stuff.txt 上传成功。
justinas@ubuntu /tmp cat file
kittens!
英文:
Go's net/http
server handles this pretty, using mime/multipart
package behind the scenes. You only need to call r.FormFile()
on your *http.Request
to get a multipart.File back.
Here's a complete example. And the result of uploading a file with curl:
justinas@ubuntu /tmp curl -i -F file=@/tmp/stuff.txt http://127.0.0.1:8080/
HTTP/1.1 100 Continue
HTTP/1.1 200 OK
Date: Tue, 24 Dec 2013 20:56:07 GMT
Content-Length: 37
Content-Type: text/plain; charset=utf-8
File stuff.txt uploaded successfully.%
justinas@ubuntu /tmp cat file
kittens!
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论