DRF使用FileUploadParser上传文件出现多余头部导致损坏如何解决
问题成因
- DRF 提供的
FileUploadParser是专门用于解析原始二进制文件流请求的解析器,它的预期请求体是纯文件二进制内容,请求头的 Content-Type 对应文件本身的类型(如image/jpeg、audio/wav等),不支持解析multipart/form-data格式的表单请求。 - 你使用 curl 的
-F参数发起请求时,会自动构造multipart/form-data格式的请求,这类格式会在文件内容前后自动添加表单分隔符、Content-Disposition 等元数据头部。使用FileUploadParser解析这类请求时,会将包含表单头部的整个请求体都识别为文件内容,最终导致保存的文件被多余内容污染损坏。 - 额外的不匹配点:如果是表单上传场景,你表单中定义的文件字段名为
upfile,但代码中取的是request.data['file'],键名不匹配也会导致取值错误。
解决方法
分两种场景选择适配方案:
方案1:保持后端现有配置,调整上传请求方式
如果你的业务场景确实适合用原始二进制流上传,不需要表单提交,只需要修改curl命令,直接传递纯文件内容即可:
curl -X PUT --data-binary @_mat/e_h_01.jpg -H "Content-Type: image/jpeg" http://localhost:8008/upload/e_h_01.jpg
说明:--data-binary参数会直接读取文件的原始二进制内容作为请求体,不会添加任何表单额外内容,匹配FileUploadParser的解析规则,保存的文件就是原始内容。
方案2:调整后端配置,适配表单上传场景
如果你的业务需要支持表单上传(比如前端使用FormData提交文件),修改后端代码即可:
- 替换视图的解析器为表单专属解析器:
from rest_framework.parsers import MultiPartParser, FormParser class FileUploadView(APIView): # 替换为表单解析器 parser_classes = [MultiPartParser, FormParser] def put(self, request, filename, format=None): # 表单的文件字段名为upfile,对应取值 file_obj = request.data['upfile'] entry = WaveFile(document=file_obj) entry.save() return Response(status=204)
- 调整后你原来的curl命令可以直接正常使用,解析器会自动剥离表单头部,提取出原始文件内容。
内容的提问来源于stack exchange,提问作者whitebear
相关产品推荐
相关产品推荐

