前端通过axios和FormData实现文件上传功能遇到的坑

axios文件上传的坑

基本的axios配置这里就不讲了。首先要确认后台的接口是否正常:用postman进行文件上传,如果文件能够上传成功,剩下的就是前端问题了,否则就先用postman将后台接口测通先。很难受这篇文章的结论是:自己的代码坑了自己

1. 文件上传时候,服务器报500错误

首先确认:通过formData上传,不用考虑enctype,axios发送请求,嗯,后台还要是通的
正常来说文件上传的时候,都是需要修改请求的Content-Type,修改为multipart/form-data来实现文件上传的功能
但是现在很神奇的报了个500错误

clipboard.png

看到报错之后,上网找了一大堆资料(重复内容一大堆,还一堆没有用的内容。。。) 还是没有解决问题。

1.1 网上的解决办法

网上的一种说法:axios配置不纯净,需要自己手动创建一个axios请求。
但是创建了之后发现请求头一直都是application/x-www-form-urlencoded(axios源码中,如果没有设置请求头的时候,axios会默认设置这个Content-Type),会导致文件没有办法上传,或者是上传之后文件是null的。

1.2 更加野的办法

在上面那个报错的截图中看到服务器是报没有boundary的错误,查了一下资料发现这个是浏览器进行分割文件时需要到的分割符,野方法就是直接手动添加一个boundary在multipart/form-data的后面。但是很无奈,发现服务器换了个报错415,显示当前的请求为不支持的媒体类型。

2 axios的配置

目前可以肯定报错就是因为发送请求时候的请求头错误,导致后端就收不到文件。百度到了一个很关键:发送文件的时候不能够手动设置multipart/form-data,需要浏览器来自行设置这个请求头

2.1 axios配置

理论上axios的配置应该没有那么蠢,没有考虑到axios需要发送formData格式的内容。正好最近一直研究在axios的源码内容,不小心被我看到了一个有趣的内容

clipboard.png

看到没有,在axios源码里面就写着,如果当前的请求内容是formData格式时候,就将Content-Type删除,也就是删除掉了multipart/form-data这个请求头。而且人家后面还写着备注说,让浏览器来继续设置这个值。终于找到了关键的地方,在这个判断前打印了一下requestData的值,结果发现是空的。继续去查看这个requestData值的内容

clipboard.png

找了这个对请求数据进行装载的地方,在装载前后打印了内容发现,装载了之后内容都被清空了,也就导致了后面判断是否为一个formData对象时候直接判断为false就无法删除Conten-Type了。

clipboard.png

这个地方就是我们自己对发送请求时候请求数据的修改,也就影响了上面装载数据的处理,可以看到如果是multipart/form-data时候,数据直接就被Qs进行序列化了,因为无法序列化FormData的内容,所以返回的data就是一个空的内容,导致最后判断是不是formData对象时出错

3. 解决办法

clipboard.png

clipboard.png

所以最后就是因为自己坑自己,很难受

你可能感兴趣的:(axios,formdata)