传带文件内容的formdata的请求头问题

给后台接口传一个带excel文件的formdata数据,后台无法解析

  • 传文件时,请求的headers的"Content-Type"应该为"multipart/form-data",这里注意不应该为"application/x-www-form-urlencoded",虽然这两个content-type都能传formdata格式的数据,但是后者只是针对键值对类型的formdata,如果包含了文件,还是需要用前者。
  • 重点注意的是,虽然知道要用multipart/form-data,但是不应该在请求接口中手动添加headers,而是不设置Content-Type,让浏览器自行判断进行添加,为什么呢?
    • 首先看下请求包的负载里的东西
------WebKitFormBoundarywNjsd2F5R7c3ihJ2
Content-Disposition: form-data; name="import_file"; filename="test.xlsx"
Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet


------WebKitFormBoundarywNjsd2F5R7c3ihJ2
Content-Disposition: form-data; name="activity_id"

30
------WebKitFormBoundarywNjsd2F5R7c3ihJ2
Content-Disposition: form-data; name="import_xls"

true
------WebKitFormBoundarywNjsd2F5R7c3ihJ2--
  • 可以看到一个“------WebKitFormBoundarywNjsd2F5R7c3ihJ2”样子的东西把formdata里的字段分隔开了,而这个东西就叫分隔符,我们再看请求头的content-type
Content-Type: multipart/form-data;boundary=----WebKitFormBoundarywNjsd2F5R7c3ihJ2
  • 这里我们是没有手动添加请求头的,是浏览器自动识别添加的,而初此之外,还多了一个叫boundary的,对比发现,这个boundary就是上面负载里的分隔符
    • 那它为什么会出现在这里呢?后台拿到了我们传过去的formdata,就需要解析,但是内容被分隔符分隔开了,而分隔符是不确定的字符串,后台怎么解析呢?就是通过我们的header拿到boundary,然后对formdata进行解析。
    • 那么为什么不能手动添加呢?手动添加也就意味着还要手动添加boundary,因为不管你有没有传boundary,浏览器都会自动给传递的formdata添加分隔符,如果不传,后台就解析不了,而这里的分隔符又是浏览器随机生成的,完全不可能手动添加,所以传文件时,记得不要写Content-Type
    • 除此之外开发的时候还有另一个问题,不知道是不是电脑问题,也不是浏览器版本的问题,反正就不知道是什么问题,浏览器不知道自动添加content-type和boundary,而在其他人的电脑上是没问题的,这时候不要总是觉得是自己的代码问题,既然在别人的电脑上能跑,就说明代码没问题,就是电脑出问题了,不要纠结太久。而且过了几天莫名其妙的又可以了,代码一点没改。
    • 至于传文件的写法,简单提一下吧
// 这里的e是上传文件事件
const fileFormData = new FormData()
fileFormData.append('import_file', e.file.originFileObj, e.file.name)
fileFormData.append('activity_id', this.actIdForDevice)
fileFormData.append('import_xls', true)
doSthApi(fileFormData).then(res => {
    console.log(res)
}
posted @ 2022-06-13 10:15  Mizuki-Vone  阅读(1789)  评论(0)    收藏  举报