您好我正在尝试将文件上传到服务器,但我发送文件时遇到了困难。我在后端使用Django,我已经设置了一个允许用户发送文件的put端点,我确认它使用邮递员按预期工作。但是,我在前端上传时遇到问题。所以这就是我的代码在前端的样子。
selectFileManually.addEventListener('change', function(event){
event.stopPropagation();
event.preventDefault();
axios.put('http://127.0.0.1:8000/api/v1/fileupload/', {
file: this.files[0]
}).then(resp => console.log(resp.data)).catch(err => console.log(err.response.data))
}
}
})
此处selectFileManually
是input[type='file']
。但是,当我发送此请求时,服务器返回时出现以下错误:"Missing filename. Request should include a Content-Disposition header with a filename parameter
当我查看有效负载时,它完全为空:“{file:{}}”即使您可以清楚地看到我提供了一个文件发送。这就是我的代码在后端看到的方式
# views.py
from django.shortcuts import render
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.parsers import FileUploadParser, MultiPartParser
import os
# Create your views here.
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
class FileUploadView(APIView):
parser_classes = (MultiPartParser, FileUploadParser, )
def put(self, request, format=None):
print(request.data)
with open(os.path.join(BASE_DIR, 'api/media', request.data['file'].name), 'wb') as f:
for chunk in request.data['file'].chunks():
f.write(chunk)
return Response(status=204)
#urls.py
from django.urls import path
from . import views
urlpatterns = [
path('fileupload/', views.FileUploadView.as_view()),
]
请有人帮助我。我知道this.files [0]不是空的,因为控制台记录了文件,它告诉我它确实是正确的内容
答案 0 :(得分:1)
根据docs,您需要为视图指定文件名参数以处理请求。这可以通过两种方式完成:
<强> 1。可以使用文件名URL关键字参数调用视图,然后将该参数设置为文件名。要实现此目的,您需要将网址模式更改为
urlpatterns = [
path('fileupload/(?P<filename>[^/]+)$', views.FileUploadView.as_view()),
]
<强> 2。如果在没有文件名URL关键字参数的情况下调用视图,则客户端必须在 Content-Disposition
HTTP标头中设置它。然后由视图中的FileUploadParser处理。 / p>
例如Content-Disposition: attachment; filename=image.jpg.
无论哪种方式,您都需要在发出请求时访问文件名。
在您的情况下,由于您的网址格式不包含文件名参数,因此您需要设置标题以包含 Content-Disposition
。
假设this.files[0]
是一个fileObject,只需执行this.files[0].name
即可获得文件名。现在在axios请求上设置标题,因此您的前端代码应如下所示。
selectFileManually.addEventListener('change', function(event){
event.stopPropagation();
event.preventDefault();
axios.put('http://127.0.0.1:8000/api/v1/fileupload/', {
file: this.files[0]
},{headers:{
'Content-Disposition': 'attachment; filename=this.files[0].name'
}
},
).then(resp => console.log(resp.data)).catch(err => console.log(err.response.data))
}
}
})
希望这有帮助!