【问题标题】:Uploading file using axios使用 axios 上传文件
【发布时间】:2018-08-29 03:45:16
【问题描述】:

您好,我正在尝试将文件上传到服务器,但在发送文件时遇到了困难。我在后端使用 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))
        }
    }
})

这里的selectFileManuallyinput[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] 不是空的,因为控制台记录了文件,它告诉我它确实是正确的内容

【问题讨论】:

    标签: django api file django-rest-framework axios


    【解决方案1】:

    根据docs,需要为视图指定一个文件名参数来处理请求。这可以通过两种方式完成:

    1.可以使用文件名 URL 关键字参数调用视图,然后将该参数设置为文件名。为此,您需要将 url 模式更改为

    urlpatterns = [
        path('fileupload/(?P<filename>[^/]+)$', views.FileUploadView.as_view()),
    ]
    

    2。如果在没有文件名 URL 关键字参数的情况下调用视图,则客户端必须在 Content-Disposition HTTP 标头中设置它。 然后由视图中的 FileUploadParser 处理。

    例如Content-Disposition: attachment; filename=image.jpg.

    无论哪种方式,您都需要在发出请求时访问文件名。 在您的情况下,由于您的 url 模式不包含文件名参数,您需要设置标题以包含 Content-Disposition

    假设this.files[0]是一个文件对象,你可以通过简单的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))
            }
        }
    })
    

    希望这会有所帮助!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-03-31
      • 2021-09-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-13
      • 2020-05-11
      • 2020-04-09
      相关资源
      最近更新 更多