亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

使用 go 處理文件上傳

使用 go 處理文件上傳

Go
慕勒3428872 2021-11-22 17:47:45
我最近開始玩圍棋,所以我還是個菜鳥,如果我犯了太多錯誤,請見諒。我一直試圖解決這個問題很長時間,但我只是不明白發生了什么。在我的 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")是一個空字符串,然后繼續,直到第一,如果其中r.FormFile返回以下錯誤: request Content-Type isn't multipart/form-data 我不明白為什么r.Method總是GET和沒有內容-類型。我嘗試以多種不同的方式執行 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"        },但這也不起作用。我用 Google 搜索過如何使用 fetch() 以及如何從 go 接收文件上傳,我發現它們與我的非常相似,我不知道我做錯了什么。
查看完整描述

2 回答

?
ABOUTYOU

TA貢獻1812條經驗 獲得超5個贊

我設法解決了我的問題,所以在這里以防其他人需要它。并感謝@JiangYD 提供使用 curl 測試服務器的技巧。


TL; 博士

我寫了,http.HandleFunc("/submit/", submit)但我正在向/submit(注意缺少的斜線)發出 POST 請求<<這很重要,因為重定向

不要自己指定 Content-Type,瀏覽器會為你做

長答案

我按照@JiangYD 說的做了,并使用curl 來測試服務器,我用響應更新了我的答案。我發現奇怪的是有一個 301 重定向,因為我沒有把它放在那里,我決定使用以下 curl 命令


curl -v -F 'uploadFile=@\"C:/Users/raul-/Desktop/test.png\"' -L http://localhost:8080/submit

(注意-L)那樣 curl 跟隨重定向,盡管它再次失敗,因為在重定向時,curl 從 POST 切換到 GET 但通過該響應我發現請求/submit被重定向到/submit/,我記得我是這樣寫的它在main函數中。


在修復它仍然失敗后,響應是http: no such file并且通過查看net/http代碼我發現這意味著該字段不存在,因此我對獲得的所有字段名稱進行了快速迭代:


for k, _ := range r.MultipartForm.File {

    log.Println(k)

}

我得到'uploadFile了字段名稱,我刪除了 curl 命令中的單引號,現在它完美地上傳了文件


但這并沒有結束,我現在知道服務器工作正常,因為我可以使用上傳文件,curl但是當我嘗試通過托管網頁上傳文件時,出現錯誤:no multipart boundary param in Content-Type.


所以我發現我應該在標題中包含邊界,我將 fetch 更改為這樣的:


fetch('/submit', {

    method: 'post',

    headers: {

        "Content-Type": "multipart/form-data; boundary=------------------------" + boundary

    }, body: formData})

我像這樣計算邊界:


var boundary = Math.random().toString().substr(2);

但是我還是有一個錯誤:multipart: NextPart: EOF那么你如何計算邊界?我閱讀了規范https://html.spec.whatwg.org/multipage/forms.html#multipart/form-data-encoding-algorithm并發現邊界是由對文件進行編碼的算法計算的,在我的情況下是 FormData,FormData API 沒有公開獲取該邊界的方法,但我發現瀏覽器會multipart/form-data自動添加 Content-Type with和邊界,如果您不指定它,所以我從fetch調用中刪除了 headers 對象和現在它終于起作用了!


查看完整回答
反對 回復 2021-11-22
?
搖曳的薔薇

TA貢獻1793條經驗 獲得超6個贊

完全刪除標題實際上有效。尤其是通過 fetch 或 axios 發送請求時。


axios.post(

                    endpoint + "/api/v1/personalslip",

                    {

                      newSlip

                    },

                    {



                     

                    }

                  )

                  .then(res => {

                    console.log(res);

                  });


查看完整回答
反對 回復 2021-11-22
  • 2 回答
  • 0 關注
  • 245 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號