我需要从基于React的前端向Django REST Framework后端发送任意文件(例如xls
)。
谷歌搜索并尝试了许多代码变体几个小时,但没有一个能完全起作用。
这是代码的重要组成部分:
1.1表单输入字段
<input
type="file"
multiple={true}
accept=".xls,.xlsx,.csv,.txt"
onChange={this.handleFilesChosen}
/>
1.2 handleFilesChosen
handleFilesChosen = event => {
this.setState({
files: event.target.files
});
}
1.3上传点击处理程序(authHeader
是替换授权承载令牌的函数)
handleUploadClick = event => {
let formData = new FormData();
for (let file of this.state.files) {
formData.append('files', file);
}
const csrf = this.getCookie('csrftoken');
fetch(`${API_BASE_PATH}/load-input-data/`, {
method: 'POST',
headers: authHeader({contentType: 'multipart/form-data', csrf: csrf}),
body: formData,
})
.then(result => result.json())
.catch(error => error);
}
class LoadInputDataView(APIView):
parser_class = (MultiPartParser,)
@method_decorator(login_required)
def post(self, request, format=None):
print(request.data)
return Response(status=status.HTTP_201_CREATED)
我选择了带有hello world
内容的简单txt文件(为了使调试容易,二进制文件将在以后发布),将其上传并在Django <QueryDict: {}>
控制台中获取runserver
。
如果我查看Chrome的“网络”标签,则会看到以下空的请求有效负载,而不是实际的文件内容:
------WebKitFormBoundaryYw6ABRFkvxatzHqi
Content-Disposition: form-data; name="files"; filename="foo.txt"
Content-Type: text/plain
------WebKitFormBoundaryYw6ABRFkvxatzHqi--
试图删除contentType
标头-消息JSON parse error
出现400错误(浏览器自动替换JSON contentType标头)。
我被困住了。有人可以引导我吗?
答案 0 :(得分:0)
找到解决方案。我不应该手动设置Content-Type
标头,而是使用boundary
选项自动设置。现在Django的request.FILES
也可以使用,我可以使用以下代码处理来自后端的上传文件:
class ParseInputDataView(APIView):
parser_class = (MultiPartParser,)
permission_classes = [permissions.IsAuthenticated]
def post(self, request, controller_id, format=None):
for file_entry in request.FILES.getlist('files'):
uploaded_file_name = file_entry.name
uploaded_file_content = file_entry.read()
...