无法使用 multer 从 req 对象访问 req.files

Posted

技术标签:

【中文标题】无法使用 multer 从 req 对象访问 req.files【英文标题】:Cannot access req.files from req object using multer 【发布时间】:2018-01-06 17:04:49 【问题描述】:

我正在尝试使用 NodeJs 脚本将文件上传到服务器。我正在尝试以下事情。

HTML

<md-tab label="Upload log">
    <md-content class="md-padding" id="popupContainer" ng-cloak>
        <h4>Upload a zip file</h4>
            <form ng-submit="$event.preventDefault()">
                <md-input-container class="md-block" flex>
                    <label>Source</label>
                    <md-select name="source" ng-model="log.source" ng-click="getSources()">
                        <md-option ng-repeat="source in sourceInfo" value="source.sourceCode">source.sourceName</md-option>
                    </md-select>
                </md-input-container>
                <br>
                <md-input-container class="md-block">
                    <label>Select Batch</label>
                    <input required type="number" step="any" name="rate" ng-model="log.batch" min="1" max="100"/>
                </md-input-container>
                <md-input-container class="md-block">
                    <label>Enter your comments about the log files</label>
                    <textarea ng-readonly="false" ng-model="log.comment" md-maxlength="100" rows="3" md-select-on-focus></textarea>
                </md-input-container>
                <div ng-if="status" id="status">
                    <b layout="row" layout-align="center center" class="md-padding">status</b>
                </div>
                <input type="file" file-model="log.file" name="inputFile"/>
                <button ng-click="uploadFiles()">Upload</button>
                log
                <p> </p>
            </form>
    </md-content>
</md-tab>

指令

var logApp = angular.module('logAnalysisApp', ['ngMaterial', 'lfNgMdFileInput', 'ngRoute', 'ngMessages']);
logApp.config(['$routeProvider', '$compileProvider', '$mdThemingProvider', function ($routeProvider, $compileProvider, $mdThemingProvider) 
            $compileProvider.debugInfoEnabled(false);
            $routeProvider
            .when('/login', 
                templateUrl: 'views/login.html',
                controller: 'loginControl'
            )
            .when('/register', 
                templateUrl: 'views/register.html',
                controller: 'registerControl'
            )
            .when('/home', 
                templateUrl: 'views/filemenu.html',
                controller: 'fileUploadCtrl'
            )
            .when('/admin', 
                templateUrl: 'views/adminpanel.html',
                controller: 'adminCtrl'
            )
            .when('/totalreport', 
                templateUrl: 'views/total.html',
                controller: 'totalCtrl'
            )
            .otherwise(
                redirectTo: '/login'
            );
        
    ])

logApp.constant('config', 
    apiUrl: 'http://localhost:8080',
    serverUrl: 'http://localhost:3000'
)

logApp.directive('fileModel', ['$parse', function ($parse) 
            return 
                restrict: 'A',
                link: function (scope, element, attrs) 
                    var model = $parse(attrs.fileModel);
                    var modelSetter = model.assign;

                    element.bind('change', function () 
                        scope.$apply(function () 
                            modelSetter(scope, element[0].files[0]);
                        );
                    );
                
            ;
        
    ]);

控制器

logApp.controller('fileUploadCtrl', function ($rootScope, $scope, $timeout, $location, $http, config) 
    $scope.log = ;
    $scope.uploadFiles = function () 

        console.log($scope.log);

        var uploadUrl = "http://localhost:3000/testRef";

        var fd = new FormData();
        for (var key in $scope.log)
            fd.append(key, $scope.log[key]);
        for (var pair of fd.entries()) 
            console.log(pair[0] + ', ' + pair[1]);
        
        $http.post(uploadUrl, fd, 
            transformRequest: angular.indentity,
            headers: 
                'Content-Type': undefined
            
        )
        .success(function () 
            console.log("success!!");
        )
        .error(function () 
            console.log("error!!");
        );
    ;
);

服务器端编码

var express = require('express')
var app = express()
var multer  = require('multer');
var upload = multer( dest: './uploads' );
app.post('/testRef', upload.any("inputFile"), function(request, response) 

    console.log(request.files)
    console.log(request.body)
    response.send("Done")
);

当我试图在控制台中查看 request.files 时,它显示空白数组,而 request.body 显示为空白对象。但是,当我打印$scope.log 时,在客户端日志中显示了适当的内容,并且在遍历 FormData 变量时,我看到了我正在发送的所需数据。此外,在我打印 log 时的 html 中,文件数据没有被填充。

欢迎任何类型的帮助。

谢谢。

【问题讨论】:

@kumbhaniBhavesh:我将req.body 作为一个空对象。因此,尝试req.body.file 可能无济于事。 【参考方案1】:

我也遇到过同样的问题,但我们的浏览器就是这样工作的,在 multer 中无法修复。

对此的解决方法是在客户端使用 javascript 来捕获提交事件,而不是使用 FormData 提交并对字段进行排序,以便输入数据在任何文件之前。

这个技巧对我有用

【讨论】:

【参考方案2】:

你必须添加标题'Content-type': 'multipart/form-data'

使用req.files[0],因为您的服务器代码中有upload.any('inputFile')

【讨论】:

【参考方案3】:

给一个名字以形成和访问 req.file("filename")

【讨论】:

它说,req.file 不是一个函数。 你有没有给表单命名并访问 request.file("fileName") &lt;form ng-submit="$event.preventDefault()" name="logInputForm"&gt;&lt;/form&gt; 是我的新表单,服务器代码是 console.log(request.file("logInputForm")) 使用 loginputform 尝试一次 你能告诉我应该尝试什么吗?因为我有点糊涂了。

以上是关于无法使用 multer 从 req 对象访问 req.files的主要内容,如果未能解决你的问题,请参考以下文章

Multer 返回 req.file 未定义

尽管创建了文件对象,但 Multer req.file 始终未定义

Req.file 在尝试使用 multer 和 cloudinary 上传图片时返回 [object, object]

如何从缓冲区中提取文件内容?

如果我不上传文件,如何从npm的multer获取请求的正文?

在nestjs中使用multer-gridfs流