【问题标题】:Django Restframework FileUpload with Angular使用 Angular 上传 Django Rest 框架文件
【发布时间】:2017-04-24 23:33:18
【问题描述】:

几个小时以来,我一直试图让 FileUpload 与 DRF 和 Angular 一起工作。我有这样的看法:

class FileUploadView(APIView):
    parser_classes = (MultiPartParser,)

    def post(self, request, pk):
         print request.FILES
         #do something
         return Response(status=204)

我正在使用 angular-file-upload (https://github.com/nervgh/angular-file-upload/wiki/Module-API) 像这样(getCookie() 函数来自 here):

var csrf = getCookie('csrftoken'); 

    $scope.uploader = new FileUploader({
        queueLimit:1,
        url:'upload',
        method: 'POST',
        headers : {
        'X-CSRF-TOKEN': csrf
        }
    });

但是,当我使用 curl 将数据发送到 url 时,它可以工作:

curl -X POST \
    --dump-header - \
    -H "Content-Type:multipart/form-data" \
    -u admin:admin \
    -F "image=@/Users/magda/test.pdf;type=application/pdf" \
http://localhost:8000/lectures/166/upload

但是每当我使用角度函数时,我都会得到:

detail: "CSRF Failed: CSRF token missing or incorrect."

我还尝试将 csrf_exempt 添加到函数中,这并没有改变任何东西。我做错了什么?

【问题讨论】:

    标签: django angularjs curl file-upload


    【解决方案1】:

    我遇到了与您使用 angular-file-upload 相同的错误。我刚刚抓取了 csrf 令牌并将其包含在我的数据中,以便 django 允许它。

    $scope.$watch('files', function() {
          if($scope.files) {
              var csrf = $cookies.csrftoken;
              for (var i = 0; i < $scope.files.length; i++) {
                  var file = $scope.files[i];
                  $scope.upload = $upload.upload({
                      url: '/api/v1/attachments/',
                      data: {csrfmiddlewaretoken: csrf, message: 6 },
                      file: file // single file or a list of files. list is only for html5
                  }).progress(function (evt) {
                      console.log('progress: ' + parseInt(100.0 * evt.loaded / evt.total) + '% file :' + evt.config.file.name);
                  }).success(function (data, status, headers, config) {
                      // file is uploaded successfully
                      console.log('file ' + config.file.name + 'is uploaded successfully. Response: ' + data);
                      data.filename = config.file.name;
                      $scope.attachedFiles.push(data);
                  }).error(function (data, status, headers, config) {
                      console.log('fail to upload ' + config.file.name + ' -  response: ' + data.details);
                  });
              }
          }
      });
    

    【讨论】:

    • 是的,我必须将 csrftoken 添加到 formdata 而不是标题中。
    【解决方案2】:

    您的 CRSF 令牌密钥可能不正确,我是这样做的(仍在计算 onBeforeUploadItem() 部分):

    App.js

    require('angular-file-upload');
    
    angular.module('app', [
        'angularFileUpload'
    ])
    

    控制器

    function controller(FileUploader, $q, $cookies, logger) {
        var vm = this;
    
        function activate() {
            vm.uploader = new FileUploader({
                url: '/api/expense-claim/' + vm.expense.id + '/transport-cost-attachment/',
                headers: {
                    'X-CSRFToken': $cookies.get('csrftoken')
                }
            });
            vm.uploader.onBeforeUploadItem = onBeforeUploadItem;
        }
    
        function onBeforeUploadItem(fileItem) {
            fileItem.formData.push({creator: vm.owner});
            fileItem.formData.push({attachment_file: fileItem.file.name});
        }
    
        activate();
    }
    

    HTML

    <input type="file" nv-file-select uploader="vm.uploader"/>
    <ul>
        <li ng-repeat="item in vm.uploader.queue">
            Name: <span ng-bind="item.file.name"></span><br/>
            <button ng-click="item.upload()">upload</button>
        </li>
    </ul>
    

    【讨论】:

      猜你喜欢
      • 2013-10-25
      • 2015-10-04
      • 2013-12-26
      • 2016-10-25
      • 1970-01-01
      • 2016-02-16
      • 2021-09-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多