NaiveUI 提供的 NUpload 组件用来上传文件,这里有个坑:该组件的模型响应变量不是原生的 File 对象,而是在 File 对象外面又套了一层:
// import type { UploadFileInfo } from 'naive-ui'
export interface FileInfo {
id: string;
name: string;
batchId?: string | null;
percentage?: number | null;
status: 'pending' | 'uploading' | 'finished' | 'removed' | 'error';
url?: string | null;
file?: File | null;
thumbnailUrl?: string | null;
type?: string | null;
fullPath?: string | null;
}
可以看到,模型响应变量的 file 成员才是真正可以添加进 FormData 的文件,直接添加 FileInfo 对象就会导致文件上传失败。
上传文件和其他参数的混合数据只能使用 multipart/form-data 这个类型:
const formData = new FormData()
// 向表单数据对象中添加一个文件,注意需要提取出 file 成员
formData.append('abundanceFile', abd.file as File)
// 向表单数据对象中添加一个普通的参数
formData.append('taskName', 'xxxxxxxx')
// 向表单数据对象中添加一个复杂数据,这里用 JSON 序列化方便服务器解包
formData.append('params', JSON.stringify(params))
在发起请求时别忘了设置 Content-Type:
const r: AxiosResponse = await axios.post('/xxx', formData, {
headers: { 'Content-Type': 'multipart/form-data' }
})
后端使用 DRF 框架,在 viewset 实例中读取文件内容:
@action(methods=['post'], detail=True, url_path='start')
def start(self, request: Request, pk):
for k in request.data:
if k == 'taskName': pass
elif k == 'params': pass
else:
f = request.data.get(k)
print(f.read().decode('utf-8'))
with open('module/test.txt', 'wb') as wt:
wt.write(f.read())
return Response(1)
也可以使用模型保存。
评论区