Tải lên tệp bằng Express 4.0: req.files không xác định


239

Tôi đang cố gắng để có một cơ chế tải lên tệp đơn giản hoạt động với Express 4.0 nhưng tôi vẫn tiếp tục sử undefineddụng req.filesphần app.postthân. Đây là mã có liên quan:

var bodyParser = require('body-parser');
var methodOverride = require('method-override');
//...
app.use(bodyParser({ uploadDir: path.join(__dirname, 'files'), keepExtensions: true })); 
app.use(methodOverride()); 
//...
app.post('/fileupload', function (req, res) {
  console.log(req.files); 
  res.send('ok'); 
}); 

.. và mã Pug đi kèm:

form(name="uploader", action="/fileupload", method="post", enctype="multipart/form-data")
    input(type="file", name="file", id="file")
    input(type="submit", value="Upload")

Giải pháp
Nhờ phản hồi của mscdex bên dưới, tôi đã chuyển sang sử dụng busboythay vì bodyParser:

var fs = require('fs');
var busboy = require('connect-busboy');
//...
app.use(busboy()); 
//...
app.post('/fileupload', function(req, res) {
    var fstream;
    req.pipe(req.busboy);
    req.busboy.on('file', function (fieldname, file, filename) {
        console.log("Uploading: " + filename); 
        fstream = fs.createWriteStream(__dirname + '/files/' + filename);
        file.pipe(fstream);
        fstream.on('close', function () {
            res.redirect('back');
        });
    });
});

1
Làm thế nào để điều này làm việc với nhiều tập tin?
chovy

@chovy nó chỉ hoạt động tốt với nhiều tệp
mscdex

2
ithink có thể làm app.post ('/ fileupload', busboy (), function (req, res) {
Shimon Doodkin

Giải pháp tốt Tôi chỉ muốn lưu ý rằng bạn phải tạo một ./files/thư mục trong thư mục chính của ứng dụng nếu không bạn sẽ gặp lỗi sau khi tải lên.
nước sốt

Các tệp tạm thời được xử lý như thế nào? Busboy có xóa chúng tự động không? Tôi chỉ không thấy các tệp tạm thời bị xóa trước khi lưu vào đĩa.
ed-ta

Câu trả lời:


210

Các body-parsermô-đun chỉ xử lý JSON và gửi biểu mẫu urlencoded, không nhiều phần dữ liệu (mà sẽ là trường hợp nếu bạn đang tải lên tệp).

Đối với nhiều phần, bạn cần sử dụng một cái gì đó giống connect-busboyhoặc multerhoặc connect-multiparty(nhiều phần / ghê gớm là những gì ban đầu được sử dụng trong phần mềm trung gian express bodyParser). Ngoài ra FWIW, tôi đang làm việc trên một lớp thậm chí cao hơn trên đầu của busboy được gọi reformed. Nó đi kèm với một phần mềm trung gian Express và cũng có thể được sử dụng riêng.


4
Cảm ơn, điều đó đã làm việc. Mặc dù tôi đã phải sử dụng connect-busboythay vì chỉ busboy. Cập nhật bài viết gốc của tôi với giải pháp.
safwanc

4
Cảm ơn bạn đời! Tôi tìm thấy connect-multipartytùy chọn tốt nhất trong số này!
neciu

reformedvẫn đang được phát triển? Cam kết cuối cùng của bạn trên github là từ năm 2014 ... Nhân tiện, theo ý kiến ​​của bạn, mô-đun tốt nhất để xử lý dữ liệu biểu mẫu nhiều phần là gì? "Tốt nhất" Tôi có nghĩa là hỗ trợ tốt nhất và hoạt động tốt hơn (ít lỗi hơn), với nhiều tính năng hơn và có tương lai lâu hơn..Tôi chọn multervì nó có vẻ được hỗ trợ tốt nhất, nhưng tôi vẫn nghĩ nó nên được hỗ trợ nhiều hơn.
nbro

[EDIT: không sao, chỉ cần xem câu trả lời bên dưới.] Đã thực hiện nhiều phần với trong Express 3.0, và sau đó bị hỏng trong 4.0? tôi hỏi vì hướng dẫn này sử dụng 3.4.8 và có thể tải lên tập tin mà không cần bất kỳ middleware thêm blog.robertonodi.me/simple-image-upload-with-express
thetrystero

@th temstero Repo github cho ví dụ cụ thể mà bạn liên kết đến thực sự có các phụ thuộc được kiểm tra trong repo. Nếu bạn tìm hiểu các phụ thuộc đó, bạn sẽ thấy Express 3.x được bao gồm, cũng như Connect 2.x (vẫn có mô-đun nhiều phần được đi kèm với nó). Đó là lý do tại sao xử lý nhiều phần đã hoạt động "ra khỏi hộp".
mscdex

31

Đây là những gì tôi tìm thấy googling xung quanh:

var fileupload = require("express-fileupload");
app.use(fileupload());

Đó là cơ chế khá đơn giản để tải lên

app.post("/upload", function(req, res)
{
    var file;

    if(!req.files)
    {
        res.send("File was not found");
        return;
    }

    file = req.files.FormFieldName;  // here is the field name of the form

    res.send("File Uploaded");


});

quá chậm đối với các tệp lớn
Eduardo

3
Bạn đã không sử dụng fileupload?
BrandonFlynn-NB

5
Để câu trả lời trên có hiệu quả, bạn cần thêm hai dòng này vào phần chính của mìnhapp.js const fileUpload = require('express-fileupload') app.use(fileUpload())
hãy bỏ qua

11

Có vẻ như body-parser đã hỗ trợ tải lên các tệp trong Express 3, nhưng hỗ trợ đã bị loại bỏ cho Express 4 khi nó hỗ trợ không còn bao gồm Connect như một phần phụ thuộc

Sau khi xem qua một số mô-đun trong câu trả lời của mscdex, tôi thấy rằng express-busboy là một sự thay thế tốt hơn nhiều và là thứ gần nhất với sự thay thế thả vào. Sự khác biệt duy nhất tôi nhận thấy là trong các thuộc tính của tệp được tải lên.

console.log(req.files)sử dụng trình phân tích cú pháp cơ thể (Express 3) xuất ra một đối tượng trông như thế này:

{ file: 
   { fieldName: 'file',
     originalFilename: '360px-Cute_Monkey_cropped.jpg',
     name: '360px-Cute_Monkey_cropped.jpg'
     path: 'uploads/6323-16v7rc.jpg',
     type: 'image/jpeg',
     headers: 
      { 'content-disposition': 'form-data; name="file"; filename="360px-Cute_Monkey_cropped.jpg"',
        'content-type': 'image/jpeg' },
     ws: 
      WriteStream { /* ... */ },
     size: 48614 } }

so với việc console.log(req.files)sử dụng express-busboy (Express 4):

{ file: 
   { field: 'file',
     filename: '360px-Cute_Monkey_cropped.jpg',
     file: 'uploads/9749a8b6-f9cc-40a9-86f1-337a46e16e44/file/360px-Cute_Monkey_cropped.jpg',
     mimetype: 'image/jpeg',
     encoding: '7bit',
     truncated: false
     uuid: '9749a8b6-f9cc-40a9-86f1-337a46e16e44' } }

8

1) Đảm bảo rằng tệp của bạn thực sự được gửi từ phía khách hàng. Ví dụ: bạn có thể kiểm tra nó trong Chrome Console: ảnh chụp màn hình

2) Đây là ví dụ cơ bản về phụ trợ NodeJS:

const express = require('express');
const fileUpload = require('express-fileupload');
const app = express();

app.use(fileUpload()); // Don't forget this line!

app.post('/upload', function(req, res) {
   console.log(req.files);
   res.send('UPLOADED!!!');
});

7

multer là một phần mềm trung gian xử lý dữ liệu đa dữ liệu / biểu mẫu dữ liệu của Google và làm cho các tệp được tải lên và dữ liệu biểu mẫu có sẵn cho chúng tôi theo yêu cầu như request.files và request.body.

cài đặt multer: - npm install multer --save

trong tệp .html: -

<form method="post" enctype="multipart/form-data" action="/upload">
    <input type="hidden" name="msgtype" value="2"/>
    <input type="file" name="avatar" />
    <input type="submit" value="Upload" />
</form>

trong tệp .js: -

var express = require('express');
var multer = require('multer');
var app = express();
var server = require('http').createServer(app);
var port = process.env.PORT || 3000;
var upload = multer({ dest: 'uploads/' });

app.use(function (req, res, next) {
  console.log(req.files); // JSON Object
  next();
});

server.listen(port, function () {
  console.log('Server successfully running at:-', port);
});

app.get('/', function(req, res) {
  res.sendFile(__dirname + '/public/file-upload.html');
})

app.post('/upload', upload.single('avatar'),  function(req, res) {
  console.log(req.files); // JSON Object
});

Hi vọng điêu nay co ich!


2

Vui lòng sử dụng mã dưới đây

app.use(fileUpload());

var fileupload = Yêu cầu ("express-fileupload"); app.use (fileupload ());
Saurabh Agarwal

0

VẤN ĐỀ GIẢI QUYẾT !!!!!!!

Hóa ra storagechức năng DID KHÔNG chạy dù chỉ một lần. vì tôi đã phải bao gồm app.use(upload)nhưupload = multer({storage}).single('file');

 let storage = multer.diskStorage({
        destination: function (req, file, cb) {
            cb(null, './storage')
          },
          filename: function (req, file, cb) {
            console.log(file) // this didn't print anything out so i assumed it was never excuted
            cb(null, file.fieldname + '-' + Date.now())
          }
    });

    const upload = multer({storage}).single('file');

-1

express-fileupload có vẻ như phần mềm trung gian duy nhất vẫn hoạt động trong những ngày này.

Với cùng ví dụ multerconnect-multipartyđưa ra giá trị không xác định của req.file hoặc req.files , nhưngexpress-fileupload hoạt động.

Và có rất nhiều câu hỏi và vấn đề được đặt ra về giá trị trống của req.file / req.files .

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.