我最近开始学习go语言,所以还是个新手,如果我犯了太多错误,请见谅。我一直在尝试修复这个问题,但是就是不明白发生了什么。在我的main.go文件中,我有一个main函数:
func main() {
http.HandleFunc("/", handler)
http.HandleFunc("/submit/", submit)
log.Fatal(http.ListenAndServe(":8080", nil))
}
处理程序函数如下所示:
func handler(w http.ResponseWriter, r *http.Request) {
data, _ := ioutil.ReadFile("web/index.html")
w.Write(data)
}
我知道这不是为网站提供服务的最佳方式。 提交函数看起来像这样:
func submit(w http.ResponseWriter, r *http.Request) {
log.Println("METHOD IS " + r.Method + " AND CONTENT-TYPE IS " + r.Header.Get("Content-Type"))
r.ParseMultipartForm(32 << 20)
file, header, err := r.FormFile("uploadFile")
if err != nil {
json.NewEncoder(w).Encode(Response{err.Error(), true})
return
}
defer file.Close()
out, err := os.Create("/tmp/file_" + time.Now().String() + ".png")
if err != nil {
json.NewEncoder(w).Encode(Response{err.Error(), true})
return
}
defer out.Close()
_, err = io.Copy(out, file)
if err != nil {
json.NewEncoder(w).Encode(Response{err.Error(), true})
return
}
json.NewEncoder(w).Encode(Response{"File '" + header.Filename + "' submited successfully", false})
}
问题出在提交函数执行时,
r.Method
是GET
,r.Header.Get("Content-Type")
为空字符串,然后它会一直执行到第一个if语句,其中r.FormFile返回以下错误:请求的Content-Type不是multipart/form-data
。我不明白为什么r.Method总是GET,而且没有Content-Type。我尝试了许多不同的方式来编写index.html,但r.Method总是GET,Content-Type为空。这是上传文件的index.html中的函数:function upload() {
var formData = new FormData();
formData.append('uploadFile', document.querySelector('#file-input').files[0]);
fetch('/submit', {
method: 'post',
headers: {
"Content-Type": "multipart/form-data"
},
body: formData
}).then(function json(response) {
return response.json()
}).then(function(data) {
window.console.log('Request succeeded with JSON response', data);
}).catch(function(error) {
window.console.log('Request failed', error);
});
}
以下是HTML代码:
<input id="file-input" type="file" name="uploadFile" />
请注意,
<main>
标签不在<body>
标签内。我认为这可能是问题所在,因此我将函数和HTML都更改为以下内容:function upload() {
fetch('/submit', {
method: 'post',
headers: {
"Content-Type": "multipart/form-data"
},
body: new FormData(document.querySelector('#form')
}).then(function json(response) {
return response.json()
}).then(function(data) {
window.console.log('Request succeeded with JSON response', data);
}).catch(function(error) {
window.console.log('Request failed', error);
});
}
<form id="form" method="post" enctype="multipart/form-data" action="/submit"><input id="file-input" type="file" name="uploadFile" /></form>
但是那也没有起作用。我在谷歌上搜索了如何使用fetch()和如何从go接收文件上传,发现它们与我的代码非常相似,我不知道我做错了什么。
更新:
在使用curl -v -F 'uploadFile=@\"C:/Users/raul-/Desktop/test.png\"' http://localhost:8080/submit
之后,我得到了以下输出:
* Trying ::1...
* Connected to localhost (::1) port 8080 (#0)
> POST /submit HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.45.0
> Accept: */*
> Content-Length: 522
> Expect: 100-continue
> Content-Type: multipart/form-data; boundary=---------------------------a17d4e54fcec53f8
>
< HTTP/1.1 301 Moved Permanently
< Location: /submit/
< Date: Wed, 18 Nov 2015 14:48:38 GMT
< Content-Length: 0
< Content-Type: text/plain; charset=utf-8
* HTTP error before end of send, stop sending
<
* Closing connection 0
当我使用curl时,在运行go run main.go
的控制台上没有任何输出。
method: post
和header: {'Content-Type': 'multipart/form-data'}
就足够了,不需要使用<form>标签,但我也尝试使用了一个类似这样的<form>标签:<form id="form" method="post" enctype="multipart/form-data" action="/submit">
,然后使用new FormData
来提交该表单中的数据,但是它并没有起作用,所以我猜想可能是其他问题。 - redsaltgo run main.go
的控制台没有记录任何内容,就好像submit函数从未运行过一样。我在Windows中使用以下命令:curl -v -F 'uploadFile=@\"C:/Users/raul-/Desktop/test.png\"' http://localhost:8080/submit
。我得到了一个HTTP/1.1 301 Moved Permanently
的响应,并说HTTP error before end of send, stop sending
,这可能解释了为什么submit函数没有运行。 - redsalt