使用 NodeJS 进行多部分文件上传
Posted
技术标签:
【中文标题】使用 NodeJS 进行多部分文件上传【英文标题】:multipart File uploads using NodeJS 【发布时间】:2013-05-08 05:52:37 【问题描述】:我在上传文件以使用 NodeJS 时遇到问题。我正在使用 Dropzone.JS 创建一个向 /file-upload 发送 POST 请求的表单:
<form action="/file-upload" class="dropzone dragndrop" id="my-awesome-dropzone"></form>
然后我在 app.js 中有一个路由:
app.post('/file-upload', routes.upload);
然后是我的处理程序:
exports.upload = function(req, res)
console.log(req.files);
res.send("OK");
但是,这里的上传函数永远不会被调用。服务器首先因此错误而崩溃:
events.js:69
throw arguments[1]; // Unhandled 'error' event
^
Error: Invalid data
at WriteStream._write (fs.js:1616:31)
at onwrite (_stream_writable.js:265:14)
at WritableState.onwrite (_stream_writable.js:94:5)
at fs.js:1628:5
at Object.wrapper [as oncomplete] (fs.js:475:5)
at process._makeCallback (node.js:321:24)
所以我不确定我应该做什么,因为这似乎不是我的错。我遵循了其他教程,并没有发现任何问题。此外,当我在 chrome 开发工具下检查我的网络时,它显示:
Request URL:http://localhost:3000/file-upload
**Request Headers**
Accept:application/json
Cache-Control:no-cache
Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryMmLSkbfQskfIcjfE
Origin:http://localhost:3000
Pragma:no-cache
Referer:http://localhost:3000/
User-Agent:Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.17 (Khtml, like Gecko) Chrome/24.0.1312.52 Safari/537.17
X-File-Name:Screenshot from 2013-03-20 12:23:42.png
X-Requested-With:XMLHttpRequest
**Request Payload**
------WebKitFormBoundaryMmLSkbfQskfIcjfE
Content-Disposition: form-data; name="file"; filename="Screenshot from 2013-03-20 12:23:42.png"
Content-Type: image/png
------WebKitFormBoundaryMmLSkbfQskfIcjfE--
【问题讨论】:
似乎没有实际传输二进制数据。 你的节点版本是多少?你能告诉你从 app.js 调用的处理程序的文件(名称和位置)吗?你是如何解析表单数据的?req.files
需要 expressjs
处理程序位于 model.js 中,这是我所有与模型相关的处理程序所在的位置。我有 expressJS
【参考方案1】:
@user568109 和@nick-fishman 是正确的;您应该为此使用 bodyParser 中间件。
请参阅下面的基本文件上传表单的示例代码。 (注意:您需要创建一个“上传”目录来存储文件。)
文件上传.js:
var express = require("express"),
app = express();
// tell express to use the bodyParser middleware
// and set upload directory
app.use(express.bodyParser( keepExtensions: true, uploadDir: "uploads" ));
app.engine('jade', require('jade').__express);
app.post("/upload", function (request, response)
// request.files will contain the uploaded file(s),
// keyed by the input name (in this case, "file")
// show the uploaded file name
console.log("file name", request.files.file.name);
console.log("file path", request.files.file.path);
response.end("upload complete");
);
// render file upload form
app.get("/", function (request, response)
response.render("upload_form.jade");
);
app.listen(3000);
views/upload_form.jade:
doctype 5
html
head
title Upload Form
body
h1 Upload File
form(method="POST", action="/upload", enctype="multipart/form-data")
input(type="file", name="file")
input(type="submit")
【讨论】:
request 返回一个文件数组,所以试试。 console.log("文件", request.files);感谢您的出色回答。像魅力一样工作。 github.com/senchalabs/connect/wiki/Connect-3.0 express.bodyParser 已被贬低 @robert mitchell 我在这个问题上遇到了麻烦,但在 multer 框架上***.com/questions/63218454/…【参考方案2】:@user568109 是正确的:您需要启用 ExpressJS 和 bodyParser。你的配置中是否有类似下面的行?
app.use(express.bodyParser( keepExtensions: true, uploadDir: '/my/files' ));
【讨论】:
【参考方案3】:尝试使用 busboy-body-parser 检索请求正文参数和文件。
start.js
var bodyParser = require('body-parser');
var busboyBodyParser = require('busboy-body-parser');
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded(
extended: true
));
// parse application/json
app.use(bodyParser.json());
//parse multipart/form-data
app.use(busboyBodyParser());
controllers/someController.js
someAction: function(req,res)
if(req.method == "POST")
res.end(JSON.stringify(req.body)+JSON.stringify(req.files));
//"text":"testx""anexo":"data":"type":"Buffer","data":....
//req.body = "text":"testx"
//req.files = "anexo":"data":"type":"Buffer","data":....
views/someController/someAction.html
<form method="post" id="multipart" enctype="multipart/form-data">
<input type="text" id="text1" name="text" value="testx" />
<input type="file" id="anexo" name="anexo" />
<input type="submit" value="Enviar" />
</form>
要创建一个上传的文件,你需要工作如果流,例如:
/* file props
"data":"type":"Buffer","data":.... ,
"fieldname":"anexo",
"originalname":"images (1).jpg",
"encoding":"7bit",
"mimetype":"image/jpeg",
"destination":"c:\\live\\sources\\uploads\\",
"filename":"eventclock_images(1)_1443706175833.jpg",
"path":"c:\\live\\sources\\uploads\\eventclock_images(1)_1443706175833.jpg",
"size":9986
*/
var fileStream = fs.createWriteStream(file.path);
fileStream.write(file.data);
fileStream.end();
fileStream.on('error', function (err)
//console.log("error",err);
);
fileStream.on('finish', function (res)
//console.log("finish",res);
);
【讨论】:
欢迎来到***,如果你想回答一个问题,那么你应该考虑提问者的情况。以上是关于使用 NodeJS 进行多部分文件上传的主要内容,如果未能解决你的问题,请参考以下文章