文件上传后清空响应

时间:2018-04-11 15:22:52

标签: rest http go response

我在Go中编写了一个小的REST api,我使用相同的函数返回带有状态代码和消息的http.Response:

type apiResponse struct {
    Status  int    `json:"status"`
    Message string `json:"message"`
}

我正在将其编组为json字符串,并使用w.Write()将其放入响应中。

API有三个端点,其中一个端点允许用户上传文件。两个工作完全正常,我得到了我期望的响应。 上传端点返回的有效回复Content-Length与我期望的消息相匹配,但当我读取它时(使用ioutil.ReadAll),它就是空的!

我做错了什么?

这是读取正文的功能:

func readResponseContent(resp *http.Response) string {
    defer resp.Body.Close()
    fmt.Println(resp)
    fmt.Println(resp.ContentLength)
    bodyBytes, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        fmt.Println("Error in response: %s", err.Error())
        os.Exit(1)
    }
    bodyString := string(bodyBytes)
    return bodyString
}

这是处理程序:

func handleSubmission(w http.ResponseWriter, r *http.Request) {

var Buf bytes.Buffer
file, header, err := r.FormFile(audioUploadKey)

if err != nil {
    log.Printf("Error uploading file: %s\n", err.Error())
    http.Error(w, err.Error(), http.StatusInternalServerError)
    return
}
defer file.Close()

jobID, _ := uuid.NewUUID()
_ = os.MkdirAll(path.Join(jobsPath, jobID.String()), 0750)

log.Printf("Received file %s\n", header.Filename)

io.Copy(&Buf, file)
fileOut, _ := os.Create(path.Join(jobsPath, jobID.String(), 

Buf.WriteTo(fileOut)
Buf.Reset()

// submit
// DO STUFF with jobID

apiResp := apiResponse{Status:http.StatusCreated, Message:jobID.String()}
jsonResp, _ := json.Marshal(apiResp)
writeJSONResponse(w, jsonResp)
return}

2 个答案:

答案 0 :(得分:1)

问题看起来好像忘记了你收到的表单的内容类型,当你发送json时,contentt-type是aplication / json,当你上传文件时,你应该使用multipart / form-data,如果你是这种情况,你就这样读了:

    import(
       "ioutil"
       "net/http"
    )
//check all posible errors, I´m assuming you just have one file per key
    func handler(w http.ResponseWriter, r *http.Request) {
        r.ParseMultipartForm(1000000) //1 MB in memory, the rest in disk
        datas := r.MultipartForm
        for k, headers := range datas.File {
            auxiliar, _ := headers[0].Open() //first check len(headers) if it's correct
            fileName:=headers[0].Filename
            file, _ := ioutil.ReadAll(auxiliar)
            // do what you need to do with the file
    }
}
at the frontEnd you should have some javascript like this:

function handleFile(url,file){
  let data=new FormData();
  data.append("key",file); //this is the key when ranging over map at backEnd
  fetch(url,{method:"PUT",body:data})
}

答案 1 :(得分:0)

发现问题...在生成响应之前,单独函数中的一段代码正在使用Body ...

学习新语言的挫折和错误:/