使用nodeJS上传文件

5

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

我找到了一些解决方案,但都是使用Ajax的,而我对此不太了解。是否有可能不使用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)
4个回答

2
如果您正在使用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)`问题是什么? - Chococo35
文件的大小是多少?检查一下你的浏览器网络调用? - Dinesh undefined
该文件大小为160556个字节,并出现了意外的标记。SyntaxError: 意外的标记 - 在解析 (/home/chococo/API/test/node_modules/body-parser/lib/types/json.js:83:15) - Chococo35
我忘记放置一个表单标签,我在输入标签中进行操作。我编辑了我的问题中的代码。即使使用正确的表单标签,我仍然遇到同样的问题。 - Chococo35
我认为应该更改这一行代码:formData.append('uploads['+i+']', file, file.name); - Dinesh undefined
显示剩余3条评论

1

关于检查数据是否为WAV文件,你最好查看文件内容,并确定它是否类似于WAV文件。

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

要确保这是一个正确的WAV文件,而且没有损坏,你需要检查那里定义的所有字段是否合理。但是一个快速的解决方案可能只是检查内容的前四个字节是否为字母“RIFF”。它不能防止损坏的文件或恶意内容,但我认为这是一个很好的起点。


嘿,谢谢。我使用 if(file.type==("audio/wav")) 来检查数据,它运行良好。但我仍然有一个问题,就是如何传递 formData 对象。 - Chococo35

1
对于json/urlencoded的限制,建议在server/config.json中进行配置,如下所示:
{
“remoting”: {
“json”: {“limit”: “50mb”},
“urlencoded”: {“limit”: “50mb”, “extended”: true}
}

请注意,loopback 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吗? - Chococo35

0

我尝试按照非常简单的AngularJS $http POST结果为“400(错误请求)”和“无效的HTTP状态码400”中所说的更改发送到URL参数的对象:

$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"}}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接