dtnd30892 2019-09-15 16:08
浏览 723

golang服务器无法解码json(字面意思为false(预期为'a')的无效字符''400“)

I am trying to send a file and json data from a client to the server, but the server does not respond to the request and fails to decode the json data but the file is received

I am using a map and I send it as a json format(avsUpload), the reason for this is that the client can have a quantity of data n and a struc is not ideal

client code:

func UploadFile(file_up string,avsUpload map[string]string){

//get file
file, err := os.Open(file_up)
if err!=nil{
     fmt.Println(red(" ERROR ")+"open file",file,err)
     return
}

defer file.Close()

//get file info
fileInfo, err := os.Stat(file_up)
if err!=nil{
     fmt.Println(red(" ERROR ")+"geting file info",err)
     return
}

//create form
body := &bytes.Buffer{}
writer := multipart.NewWriter(body)
part, err := writer.CreateFormFile("file", fileInfo.Name())
if err != nil {
     fmt.Println(red(" ERROR ")+"creating form file",err)
     return
}

io.Copy(part, file)
writer.Close()

//encode json, avsUpload as map
json.NewEncoder(body).Encode(avsUpload)

//create request
request, err := http.NewRequest("POST", "http://127.0.0.1:2047/ctrl/upload", body)
if err != nil {
    fmt.Println(red(" ERROR "),err)
    return
}

//add headers
request.Header.Add("Content-Type", writer.FormDataContentType())
request.Header.Add("Content-Type","application/json; charset=utf-8")
request.Header.Add("Authorization", "BEARER "+readKey())
request.Header.Add("Content-Length", strconv.FormatInt(request.ContentLength,10))

//create req 
client := &http.Client{}
response, err := client.Do(request)
if err != nil {
    fmt.Println(red(" ERROR "),err)
    return
}
defer response.Body.Close()

content, err := ioutil.ReadAll(response.Body) 
if err != nil {
   fmt.Println(red(" ERROR "),err)
}

fmt.Println(" "+string(content))
}

capturing the requests, I could see that json data is sent normally

server code:

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

//set header
w.Header().Set("Content-Type", "multipart/form-data")
w.Header().Set("Content-Type", "application/json")


//set max request size
r.Body = http.MaxBytesReader(w, r.Body, MaxFileSize)

fmt.Println("size>>> ",r.ContentLength)
//close conection if request is > MaxFileSize
if r.ContentLength > MaxFileSize  {
     http.Error(w, "File size is too large, max "+strconv.Itoa(FileSize)+" mb's
", http.StatusExpectationFailed)
     log.Error(w, "File size is too large, max "+strconv.Itoa(FileSize)+" mb's", http.StatusExpectationFailed)
     return
} 

//create miltipart reader   
reader, err := r.MultipartReader()
if err != nil {
    log.Error(w, err.Error(), http.StatusBadRequest)
    return
}

// parse file form
p, err := reader.NextPart()
if err != nil && err != io.EOF {
    log.Error(w, err.Error(), http.StatusInternalServerError)
    return
}

//check if te variable file exist in form
if p.FormName() != "file" {
    http.Error(w, "file is expected
", http.StatusBadRequest)
    log.Error(w, "file is expected", http.StatusBadRequest)
    return
}

//check file name length 
if len(p.FileName()) > 100 {
    http.Error(w, "file name is too long
", http.StatusBadRequest)
    log.Error(w, "file name is too long", http.StatusBadRequest)
    return
}

//check if te filename contains spaces
var fileName string
if strings.Contains(p.FileName(), " "){
    fileName=strings.Replace(p.FileName(), " ", "_", -1)
}else{
    fileName=p.FileName()
}

//get user from id in token
_, claims, err := jwtauth.FromContext(r.Context()) 
if err != nil {
    log.Error(w, err.Error(), http.StatusBadRequest)
    return
}
user:=getUser(int(claims["id"].(float64)))

//create buffer   
buf := bufio.NewReader(p)

//upload file to user dir
f, err := os.OpenFile("test/"+user+"/tmpfile/"+fileName, os.O_WRONLY|os.O_CREATE, 0666)
if err != nil {
   log.Error(w, err.Error(), http.StatusInternalServerError)
   return
}
defer f.Close()

//decode json from client
avsSelect:=make(map[string]string)
err = json.NewDecoder(r.Body).Decode(&avsSelect)
if err != nil {
      log.Error(w, err.Error(), http.StatusBadRequest)
      return
    }

//copy file to user dir
lmt := io.MultiReader(buf, io.LimitReader(p, MaxFileSize - 511))
fileSize, err := io.Copy(f, lmt)
if err != nil && err != io.EOF {
    http.Error(w, "File size is too large, max "+strconv.Itoa(FileSize)+" mb's
", http.StatusExpectationFailed)
    log.Error(w, err.Error(), http.StatusInternalServerError)
    os.Remove(f.Name())
    return
}

defer p.Close()

//print conformation message
w.Write([]byte(fmt.Sprintf(green("SERVER: ")+"File "+fileName+" uploaded")))
fmt.Sprintf("File "+fileName+" uploaded")
log.Info("Size request: %#v
", r.ContentLength)
log.Info("Size file uploaded: %#v
",fileSize)
return
}

The server records the following for diferents request:

invalid character ' ' in literal false (expecting 'a')400
invalid character '¥' looking for beginning of value400"
invalid character '\\u0086' looking for beginning of value400"
  • 写回答

2条回答

  • duandanbeng1829 2019-09-15 16:15
    关注

    It could be an issue with your JWT auth since you're ignoring that potential error coming from jwtauth.FromContext. Try adding error handling there and see if you get anything useful.

    评论

报告相同问题?

悬赏问题

  • ¥15 java如何提取出pdf里的文字?
  • ¥100 求三轴之间相互配合画圆以及直线的算法
  • ¥100 c语言,请帮蒟蒻写一个题的范例作参考
  • ¥15 名为“Product”的列已属于此 DataTable
  • ¥15 安卓adb backup备份应用数据失败
  • ¥15 eclipse运行项目时遇到的问题
  • ¥15 关于#c##的问题:最近需要用CAT工具Trados进行一些开发
  • ¥15 南大pa1 小游戏没有界面,并且报了如下错误,尝试过换显卡驱动,但是好像不行
  • ¥15 自己瞎改改,结果现在又运行不了了
  • ¥15 链式存储应该如何解决