【问题标题】:Uploading file from form to server将文件从表单上传到服务器
【发布时间】:2016-08-26 10:06:27
【问题描述】:

我目前正在处理仪表板,现在已经卡了几个小时......我喜欢做的是有一个包含 3 个<input type="file"> 的表格(其中两个允许多个文件,一个不允许) ,并且他们每个人都发布到服务器中的 3 个不同的后期方法。当我尝试在服务器端控制台记录请求时,数据为空 ({}) 。我不明白为什么,有人可以帮我解决这个问题吗?

我正在使用 angularjs 和 nodejs 顺便说一句。

这是我当前的代码:(文件和路径是虚拟名称)

HTML:

 <form role="form" enctype="multipart/form-data">
        <div class="form-group">
            <label for="file1">File1:</label> 
            <input type="file" id="file1" accept=".txt, .json" multiple> 
        </div>
        <div class="form-group">
            <label for="file2">File2:</label> 
            <input type="file" id="file2" accept=".json"> 
        </div>
        <div class="form-group">
            <label for="file3">File3:</label>
            <input type="file" id="file3" multiple> 
        </div>
        <button type="button" ng-click="save()" class="btn btn-default"> Save</button>
    </form>

JS:

module.exports = function($scope, $http) {
        $scope.save = function () {
              file1(document.getElementById('file1').files);
              file2(document.getElementById('file2').files);
              file3(document.getElementById('file3').files);
        };

        function file1(files) { 
            $http.post('/file1', {f: files}).success(function (res) {
               //todo
            });
        };

        function file2(files) { 
            $http.post('/file2', {f: files}).success(function (res) {
              //todo
            });
        };

        function file3(files) { 
            $http.post('/file3', {f: files}).success(function (res) {
              //todo
            });
        };
 }

服务器.js

var express = require("express"),
    fs = require("fs"),
    bodyParser = require('body-parser'),

    app.use(express.static("build"));
    app.use(bodyParser());

    app.post('/file1', function (req, res) {
       console.log(req.body.f) // returns empty: {} 
       // like to move files to path: a/b/c
    });

    app.post('/file2', function (req, res) {
       // like to move files to path: a/d/e
    });

    app.post('/file3', function (req, res) {
      // like to move files to path: a/f/g
    });

更新:

在收到GrimurD的回复后,我已经修改了server.js,但还是很吃力。有接盘侠吗?

var express = require("express"),
        fs = require("fs"),
        bodyParser = require('body-parser'),
        multer = require('multer'), //<-- updated
        upload =  multer({ dest: './uploads/' }) //<-- updated

    app.use(express.static("build"));
    app.use(bodyParser());
    app.use(multer({ dest: './uploads/' }).array()); // <-- updated

    app.post('/file1', upload.array('file1'), function (req, res) {
       console.log(req.body.f) // returns empty: {} 
       console.log(req.files); // returns undefined // <-- updated
       // like to move files to path: a/b/c
    });

    app.post('/file2', upload.single('file2'), function (req, res) {
       console.log(req.file); // returns undefined  // <-- updated
       // like to move files to path: a/d/e
    });

    app.post('/file3', upload.array('file3'), function (req, res) {
      console.log(req.files); // returns undefined // <-- updated
      // like to move files to path: a/f/g
    });

【问题讨论】:

  • 我对 angularjs 或 node.js 不太了解,但根据我在 PHP 方面的经验,我可以说如果我们要上传文件,我们必须将 enctype 属性赋予表单,例如

标签: javascript angularjs node.js http


【解决方案1】:

上传文件时,表单必须使用 body-parser 不支持的 multipart/form-data。您必须使用专门的中间件来处理这种类型。 Multer 是我成功使用的一种。

【讨论】:

    【解决方案2】:

    您可以在输入字段中的 File 对象上使用 FileReader.readAsDataURL(..) 来解决此问题。我经常喜欢在文件输入类型上使用多选功能,这样我就可以上传一堆文件并异步执行此操作。

    所以我通常做的是访问输入元素上的 files 属性并循环遍历它们,然后我使用 FileReader.readAsDataURL 获取文件的二进制文件的 base64,然后将 base64 传递给带有签名的 webserivce 方法接受 base64 的字符串参数,将 b64 转换为二进制,然后您就可以重新开始工作了。

    var fileRunner = {
      files: [],
      run: function(el) {
        this.files = el.files;
        this.read();
      },
      read: function() {
    
        // begin the read operation
        console.log(this.files.length);
        for (var i = 0; i <= this.files.length - 1; i++) {
          var reader = new FileReader();
          reader.readAsDataURL(this.files[i]);
          reader.onload = this.process
        }
    
      },
      process: function(evt) {
        var result = evt.target.result
        if (result.length > 0) {
          var parts = result.split(',')
          var dataBsf = parts[parts.length - 1];
          console.log(dataBsf);
          //call method to pass the base 64 here. 
        }
      }
    };
    <body>
      <input id="fup" type="file" multiple="multiple" onchange="fileRunner.run(this)" />
    </body>

    我没有在其中包含服务器端组件,因为我认为这应该是不可知的,并且稍微超出了这里的范围。

    我只是将输出记录到控制台,但您会获取输出并将其泵送到 Web 服务。

    此外,我使用“this”在 onchange 事件处理程序中引用了输入元素,因为我不知道您想如何处理它。允许传递一个元素对我来说提供了一些松散的假设。

    【讨论】:

    • 给我一些,我可以把一些东西放在一起。
    • 这对你有用吗?如果是这样,您能否将此标记为已回答或发布有问题的回复?谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-27
    • 1970-01-01
    • 1970-01-01
    • 2012-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多