$http.post:大文件不起作用

Bar*_*nni 5 node.js express angularjs body-parser ng-file-upload

我正在尝试使用以下代码通过我的网络应用程序上传文件。

看法:

  <form name="uploadForm" class="form-horizontal col-sm-12">
    <div class="col-sm-4">
      <input type="file" ng-model="rsdCtrl.viewData.file" name="file"/>
    </div>
    <div class="col-sm-4">
      <button class="btn btn-success" type="submit" ng-click="uploadFile()">Upload</button>
    </div>
  </form>
Run Code Online (Sandbox Code Playgroud)

控制器:

function uploadFile(){
  if (uploadForm.file.$valid && file) {
    return uploadService.upload(vd.file, "Convictions Calculator", "PCCS").then(function(response){
      /* Some stuff */
    }).catch(handleServiceError);
  }
}
Run Code Online (Sandbox Code Playgroud)

上传服务:

(function (){
'use strict';
angular.module('cica.common').service('uploadService', ['$http', '$routeParams', uploadService]);

function uploadService($http, $routeParams) {

    this.upload = function (file, name, type) {
        const fd = new FormData();
        fd.append('document', file);
        fd.append('jobId', $routeParams.jobId);
        fd.append('documentRename', name);
        fd.append('documentType', type);

        return $http.post('/document/upload', fd, {
            transformRequest: angular.identity,
            headers: {'Content-Type': undefined}
        }).catch(function(err){
            handleHttpError('Unable to upload document.', err);
        });
    };
  }
})();
Run Code Online (Sandbox Code Playgroud)

路线.js:

    'POST /document/upload': {controller: 'DocumentController', action: 'uploadDocument'},
Run Code Online (Sandbox Code Playgroud)

文档控制器:

"use strict";
const fs = require('fs');

module.exports = {
  uploadDocument: function (req, res) {
    console.log(req.allParams());   //Inserted as part of debugging
    const params = req.allParams();
    req.file('document').upload({
        // don't allow the total upload size to exceed ~100MB
        maxBytes: 100000000
    }, function whenDone(err, uploadedFiles) {
        if (err) {
            return res.serverError(err);
        }
        // If no files were uploaded, respond with an error.
        else if (uploadedFiles.length === 0) {
            return res.serverError('No file was uploaded');
        } else {
            const filePath = uploadedFiles[0].fd;
            const filename = uploadedFiles[0].filename;
            return fs.readFile(filePath, function (err, data) {
                if (err) {
                    return res.serverError(err);
                } else {
                    const jobId = params.jobId;
                    const jobVars =
                        {
                            filePath: results.filePath,
                            fileName: params.documentRename,
                            fileType: params.documentType
                        };
                    return DocumentService.uploadConvictions(req.session.sessionId, jobId, jobVars).then(function (response) {
                        return res.send("Document uploaded.");
                    }).catch(function (err) {
                        return res.serverError(err);
                    });
                }
            });
        }
    });
},
Run Code Online (Sandbox Code Playgroud)

如果我上传一个 .jpeg(大约 11kB),上传会完全按照预期进行,但是,如果我尝试上传一个更大的 .jpeg(大约 170kB),它就会失败。虽然没有立即抛出/捕获错误,但发生的情况是在上传服务中创建的 formData 对象似乎丢失了其数据。如果我在它的值上断点,它会为较大的文件返回空,这最终会在函数尝试进一步使用这些变量时导致错误。您可以通过此方法上传的文件的大小是否受到某种限制,或者我是否配置错误?

geo*_*awg 1

上传大文件时避免使用FormData API 1

\n

FormData API以base64 格式对数据进行编码,这会增加 33% 的额外开销。

\n

不发送FormData,而是直接发送文件:

\n
app.service(\'fileUpload\', function ($http) {\n    this.uploadFileToUrl = function (url, file) {\n        \xcc\xb6v\xcc\xb6a\xcc\xb6r\xcc\xb6 \xcc\xb6f\xcc\xb6d\xcc\xb6 \xcc\xb6=\xcc\xb6 \xcc\xb6n\xcc\xb6e\xcc\xb6w\xcc\xb6 \xcc\xb6F\xcc\xb6o\xcc\xb6r\xcc\xb6m\xcc\xb6D\xcc\xb6a\xcc\xb6t\xcc\xb6a\xcc\xb6(\xcc\xb6)\xcc\xb6;\xcc\xb6\n        \xcc\xb6f\xcc\xb6d\xcc\xb6.\xcc\xb6a\xcc\xb6p\xcc\xb6p\xcc\xb6e\xcc\xb6n\xcc\xb6d\xcc\xb6(\xcc\xb6\'\xcc\xb6f\xcc\xb6i\xcc\xb6l\xcc\xb6e\xcc\xb6\'\xcc\xb6,\xcc\xb6 \xcc\xb6f\xcc\xb6i\xcc\xb6l\xcc\xb6e\xcc\xb6)\xcc\xb6;\xcc\xb6\n        \xcc\xb6r\xcc\xb6e\xcc\xb6t\xcc\xb6u\xcc\xb6r\xcc\xb6n\xcc\xb6 \xcc\xb6$\xcc\xb6h\xcc\xb6t\xcc\xb6t\xcc\xb6p\xcc\xb6.\xcc\xb6p\xcc\xb6o\xcc\xb6s\xcc\xb6t\xcc\xb6(\xcc\xb6u\xcc\xb6r\xcc\xb6l\xcc\xb6,\xcc\xb6 \xcc\xb6f\xcc\xb6d\xcc\xb6,\xcc\xb6 \xcc\xb6{\xcc\xb6\n        return $http.post(url, file, {\n            transformRequest: angular.identity,\n            headers: { \'Content-Type\': undefined }\n        });\n    };\n});\n
Run Code Online (Sandbox Code Playgroud)\n

当浏览器发送 时FormData,它会使用\'Content-Type\': multipart/formdata每个部分并使用 base64 进行编码。

\n

当浏览器发送文件(或 blob)时,它将内容类型设置为文件(或 blob)的 MIME 类型。它将二进制数据放入请求正文中。

\n
\n

如何启用2<input type="file">的工作ng-model

\n

该指令开箱即用,ng-model不适用于input type="file". 它需要一个指令:

\n
app.directive("selectNgFile", function() {\n  return {\n    require: "ngModel",\n    link: function postLink(scope,elem,attrs,ngModel) {\n      elem.on("change", function(e) {\n        var files = elem[0].files[0];\n        ngModel.$setViewValue(files);\n      })\n    }\n  }\n});\n
Run Code Online (Sandbox Code Playgroud)\n

用法:

\n
app.service(\'fileUpload\', function ($http) {\n    this.uploadFileToUrl = function (url, file) {\n        \xcc\xb6v\xcc\xb6a\xcc\xb6r\xcc\xb6 \xcc\xb6f\xcc\xb6d\xcc\xb6 \xcc\xb6=\xcc\xb6 \xcc\xb6n\xcc\xb6e\xcc\xb6w\xcc\xb6 \xcc\xb6F\xcc\xb6o\xcc\xb6r\xcc\xb6m\xcc\xb6D\xcc\xb6a\xcc\xb6t\xcc\xb6a\xcc\xb6(\xcc\xb6)\xcc\xb6;\xcc\xb6\n        \xcc\xb6f\xcc\xb6d\xcc\xb6.\xcc\xb6a\xcc\xb6p\xcc\xb6p\xcc\xb6e\xcc\xb6n\xcc\xb6d\xcc\xb6(\xcc\xb6\'\xcc\xb6f\xcc\xb6i\xcc\xb6l\xcc\xb6e\xcc\xb6\'\xcc\xb6,\xcc\xb6 \xcc\xb6f\xcc\xb6i\xcc\xb6l\xcc\xb6e\xcc\xb6)\xcc\xb6;\xcc\xb6\n        \xcc\xb6r\xcc\xb6e\xcc\xb6t\xcc\xb6u\xcc\xb6r\xcc\xb6n\xcc\xb6 \xcc\xb6$\xcc\xb6h\xcc\xb6t\xcc\xb6t\xcc\xb6p\xcc\xb6.\xcc\xb6p\xcc\xb6o\xcc\xb6s\xcc\xb6t\xcc\xb6(\xcc\xb6u\xcc\xb6r\xcc\xb6l\xcc\xb6,\xcc\xb6 \xcc\xb6f\xcc\xb6d\xcc\xb6,\xcc\xb6 \xcc\xb6{\xcc\xb6\n        return $http.post(url, file, {\n            transformRequest: angular.identity,\n            headers: { \'Content-Type\': undefined }\n        });\n    };\n});\n
Run Code Online (Sandbox Code Playgroud)\n