使用 nodeJS 上传文件

Posted

技术标签:

【中文标题】使用 nodeJS 上传文件【英文标题】:Upload file with nodeJS 【发布时间】:2017-11-01 04:23:12 【问题描述】:

我在使用 nodeJS 和 Angular 上传文件时遇到问题。

我找到了解决方案,但它只适用于我不知道的 Ajax。可以不用吗?

使用以下代码我收到此错误:

POST http://localhost:2000/database/sounds 413 (Payload Too Large)

代码:

html

<div class="form-group">
        <label for="upload-input">This needs to be a .WAV file</label>
        <form enctype="multipart/form-data" action="/database/sounds" method="post">
            <input type="file" class="form-control" name="uploads[]" id="upload-input" multiple="multiple">
        </form>
        <button class="btn-primary" ng-click="uploadSound()">UPLOAD</button>
    </div>

javascript

$scope.uploadSound = function()
    var x = document.getElementById("upload-input");
    if ('files' in x) 
        if (x.files.length == 0) 
            console.log("Select one or more files.");
         else 
            var formData = new FormData();
            for (var i = 0; i < x.files.length; i++) 
                var file = x.files[i];
                if(file.type==("audio/wav"))
                    console.log("Importing :");
                    if ('name' in file) 
                        console.log("-name: " + file.name);
                    
                    if ('size' in file) 
                        console.log("-size: " + file.size + " bytes");
                    
                    formData.append('uploads[]', file, file.name);
                else
                    console.log("Error with: '"+file.name+"': the type '"+file.type+"' is not supported.");
                  
            
            $http.post('/database/sounds', formData).then(function(response)
                console.log("Upload :");
                console.log(response.data);
            );

        
     

NodeJS:

//Upload a sound
app.post('/database/sounds', function(req, res)
  var form = new formidable.IncomingForm();

  // specify that we want to allow the user to upload multiple files in a single request
  form.multiples = true;

  // store all uploads in the /uploads directory
  form.uploadDir = path.join(__dirname, '/database/sounds');

  // every time a file has been uploaded successfully,
  // rename it to it's orignal name
  form.on('file', function(field, file) 
    fs.rename(file.path, path.join(form.uploadDir, file.name));
  );

  // log any errors that occur
  form.on('error', function(err) 
    console.log('An error has occured: \n' + err);
  );

  // once all the files have been uploaded, send a response to the client
  form.on('end', function() 
    res.end('success');
  );

  // parse the incoming request containing the form data
  form.parse(req);
);

编辑:

错误变成了

POST http://localhost:2000/database/sounds 400 (Bad Request)

【问题讨论】:

【参考方案1】:

如果您使用的是 bodyParser

app.use(bodyParser.urlencoded(limit: '100mb',extended: true));
app.use(bodyParser.json(limit: '100mb'));

这将允许您上传最大 100mb 的文件

【讨论】:

我这样做了,现在错误变成了POST http://localhost:2000/database/sounds 400 (Bad Request)这是什么问题? 文件大小是多少?检查您的浏览器网络调用? 文件重 160556 字节,我得到了一个意外的令牌 SyntaxError: Unexpected token - at parse (/home/chococo/API/test/node_modules/body-parser/lib/types/json.js:83:15) enctype="multipart/form-data" 应该在表单标签中吧? 我忘了放一个表单标签,我在输入标签中这样做了。我在我的问题中编辑了代码。即使使用正确的表单标签,我仍然遇到同样的问题【参考方案2】:

对于json/urlencoded的限制,建议在server/config.json中配置如下:


“remoting”: 
“json”: “limit”: “50mb”,
“urlencoded”: “limit”: “50mb”, “extended”: true

请注意环回 REST api 有自己的 express 路由器和 bodyParser.json/urlencoded 中间件。添加全局中间件时,它必须位于 boot() 调用之前。

var loopback = require('loopback');
var boot = require('loopback-boot');

var app = module.exports = loopback();

//request limit 1gb
app.use(loopback.bodyParser.json(limit: 524288000));
app.use(loopback.bodyParser.urlencoded(limit: 524288000, extended: true));

【讨论】:

环回有什么用?如果我不需要导入大文件,我可以继续使用 express 吗?【参考方案3】:

关于检查数据是否真的是 WAV 文件,最好的办法是查看文件的内容并确定它是否看起来像 WAV 文件。

WAVE PCM soundfile format 文章详细介绍了格式。

要绝对确定这是一个正确的 WAV 文件,并且没有以某种方式损坏,您需要检查其中定义的所有字段是否有意义。但一个快速的解决方案可能是检查内容的前四个字节是否是字母“RIFF”。它不会防范损坏的文件或恶意内容,但我认为这是一个很好的起点。

【讨论】:

嘿,谢谢,我用:if(file.type==("audio/wav")) 来检查数据,它工作正常。但是我在传递 formData 对象时仍然遇到问题【参考方案4】:

我尝试更改发送到 url 参数的对象,如 Very Simple AngularJS $http POST Results in '400 (Bad Request)' and 'Invalid HTTP status code 400' 中所述:

$http.post(
                method: 'POST',
                url: '/upload',
                data: formData,
                headers: 'Content-Type': 'application/x-www-form-urlencoded',
                transformRequest: function(obj) 
                    var str = [];
                    for(var p in obj)
                    str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
                    return str.join("&");
                
            ).success(function(response)
                console.log("Uploaded :");
                console.log(response.data);
            );

但我收到一个错误的请求错误

为什么没有收到数据?之前的 console.log 显示我的 formData 中有一个文件。

错误:$http:badreq 错误的请求配置

Http request configuration url must be a string or a $sce trusted 
object.  Received: "method":"POST","url":"/upload","data":
,"headers":"Content-Type":"application/x-www-form-urlencoded"

【讨论】:

以上是关于使用 nodeJS 上传文件的主要内容,如果未能解决你的问题,请参考以下文章

使用 nodeJS 上传文件

如何使用 NodeJS 将文件或图像上传到服务器

使用 NodeJS 进行多部分文件上传

使用 NodeJS 将文件上传到 Amazon S3

如何使用 NodeJs 代理多个文件上传?

Nodejs 使用 FormData 将文件上传到 Strapi