問題
Goのウェブフレームワークrevelでファイルをアップロードしたい。
のに、nil
がアップロードされてくる。
ナンデヤ
app/views/Test/Index.html
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> </head> <body> <h1>テストデータのアップロードページ</h1> <form name="upload" method="POST" action="/test/upload"> <input type="file" name="imgFile" accept="image/png"> <input type="submit" name="submit" value="commit"> </form> </body> </html>
conf/routes
GET /test Test.Index POST /test/upload Test.Upload
app/controllers/app.go
import ( "github.com/robfig/revel" "labix.org/v2/mgo" "otiai10/logServer/app/routes" "fmt" "os" ) type Test struct { *revel.Controller } func (c Test) Index() revel.Result { return c.Render() } func (c Test) Upload(submit string, imgFile *os.File) revel.Result { fmt.Printf("submit => %v\n", submit) fmt.Printf("imgFile => %v\n", imgFile) return c.Redirect(routes.Test.Index()) }
で、/test
にアクセスしてファイルを選択してcommit押すと、サーバコンソールでは
submit => commit imgFile => <nil>
あらーん。ナンデヤ
そういえば...
むかしRailsやってて同じような問題に出会った気がする...
解決
HTMLのformタグにenctype="multipart/form-data"
属性を追加
app/views/Test/Index.html抜粋
<form name="upload" method="POST" action="/test/upload" enctype="multipart/form-data"> <input type="file" name="imgFile" accept="image/png"> <input type="submit" name="submit" value="commit"> </form>
revel clean
をしたあと、同じように/test
にアクセスしてファイルアップロードすると、
submit => commit imgFile => &{0xc2000f78d0}
ビンゴであった
formのenctypeって何なの
ファイルの中身はバイナリファイルだったりテキストでもサイズが大きかったりするので、通常のURLエンコードでの送信は無理があります。この場合は、form要素のenctype属性をmultipart/form-dataに設定し、MIMEのマルチパートデータとしてファイルやその他の項目の内容を送ります。。
http://www.kanzaki.com/docs/html/htminfo32.html#enctype
なるほど、今回はちゃんと理解したでござる
DRY