Go-接受HTTP POST多部分文件

8
我正在尝试弄清如何在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", // 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

File stuff.txt uploaded successfully.%                                                                                              
justinas@ubuntu /tmp cat file
kittens!

谢谢,我会检查这个的。我确定它会起作用,因为我在阅读一些其他示例/Github 的时候认出了你的名字。 - Jayrox
我已经更新了原始问题,包括我的现有代码和你的代码。你有什么建议吗?我做错了什么吗? - Jayrox
你的例子对我有效(再次使用curl)。问题可能出现在你的HTML表单中,而不是Go处理程序中。首先,一个常见的问题是忘记设置正确的enctypemultipart/form-data)。 - justinas
谢谢!事实证明问题不是出在Go,而是在于nginx的最大上传文件大小限制。将其更改为50MB后一切顺利。 - Jayrox

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接