最近产品提了个需求,要根据Excel文件批量录入数据。我是第一次做文件导入,所以参考老代码摸索了出来。
统一请求工具的Content-Type
因为这个系统平台之前没有做过文件导入,所以里面的Content-Type都写为了application/x-protobuf。这种情况会报错,我这里后端接口返回错误如下(这里后端设置了,可能有其他情况)。
可以在控制面板里看请求标头,如下图:
这样就要更改请求工具了。
Content-Type变化
目前需要对Content-Type进行判断识别。让Content-Type在Excel传递时变为multipart/form-data。
之前的请求都是给工具传递{url: xxxxx,data,method: 'POST'},每次请求都自动给Content-Type赋值。现在改一下Excel的请求,与其他请求分开{url: xxxxx,body,method: 'POST'},把data,换成body,方便做判断。判断如下:主要逻辑是根据options这个对象里的body是否存在,存在就不强制设置Content-Type。
let headers2 = ''
if (options.body) {
headers2 = tokenRequired ? {
...{
'Authorization': util.cookies.get('token')
},
...headers
} : {
...headers
}
} else {
headers2 = tokenRequired ? {
...{
'Content-Type': 'application/x-protobuf',
'Authorization': xxxxxx
},
...headers
} : {
...{
'Content-Type': 'application/x-protobuf',
},
...headers
}
}
new FormData()自动带上Content-Type
使用 FormData() 构造函数,浏览器会自动识别并添加请求头 "Content-Type: multipart/form-data",且参数依然像是表单提交时的那种键值对。
let uploadFormData = new FormData();
uploadFormData.append("file", file);
uploadFormData.append("fileName", "file");
this.uploadAry.push(uploadFormData);
file参数是读取文件时到对象,经过组件〈el-upload〉属性:before-upload="beforeUpload"读取。
this.uploadAry参数就是请求接口时到参数。根据数组元素,单独请求接口。
this.uploadAry.forEach(async (res) => {
// console.log('>>>>>>>>>>res',res);
await productImport(res).then((suc) => {
if (suc.errorMsg == "Success") {
}
});
});
最终结果
请求标头自动带上Content-Type: multipart/form-data
文件被数据解析如下: