Home > Back-end >  NodeJS application doesn't upload files
NodeJS application doesn't upload files

Time:04-26

Good morning to all,

I am developing a very simple JavaScript application with NodeJS. Simply upload files and view their content by paragraphs.

The problem is that every time I upload a file, I get the error "No files were uploaded." which corresponds to the following lines:

app.post('/upload_file', (req, res) => {
     if (!req.files || !req.files.filetoupload) {
         return res.status(400).send('No files were uploaded.');
     }
     
     [...]
}

This is the complete code:

const express = require('express');
const app = express();
const bodyParser = require('body-parser');
const fs = require('fs');
const sqlite3 = require('sqlite3').verbose();

app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());

if (!fs.existsSync('./db')) {
    fs.mkdirSync('./db');
}
if (!fs.existsSync('./uploads')) {
    fs.mkdirSync('./uploads');
}
let db = new sqlite3.Database('./db/paragraphs.db', sqlite3.OPEN_READWRITE | sqlite3.OPEN_CREATE, (err) => {
    if (err) {
        console.error(err.message);
    }
    console.log('Connected to the paragraphs database.');
});

db.run('CREATE TABLE IF NOT EXISTS paragraphs (id INTEGER PRIMARY KEY AUTOINCREMENT, text TEXT, tag TEXT)', (err) => {
    if (err) {
        console.error(err.message);
    }
    console.log('Created paragraphs table.');
});

app.get('/', (req, res) => {
    res.send('<h1>Hello World!</h1>'  
        '<meta charset="utf-8">'  
        '<a href="/file_uploading">Upload File</a><br>'  
        '<a href="/visualize_paragraphs">Visualize Paragraphs</a><br>'  
        '<a href="/tag_paragraphs">Tag Paragraphs</a>');
});

app.get('/file_uploading', (req, res) => {
    res.send('<h1>File Uploading</h1>'  
        '<meta charset="utf-8">'  
        '<form action="/upload_file" method="post" enctype="multipart/form-data">'  
        '<input type="file" name="filetoupload"><br>'  
        '<input type="submit">'  
        '</form>');
});

app.post('/upload_file', (req, res) => {
    if (!req.files || !req.files.filetoupload) {
        return res.status(400).send('No files were uploaded.');
    }

    let file = req.files.filetoupload;
    let filename = file.name;

    fs.writeFile('./uploads/'   filename, data, (err) => {
        if (err) {
            return console.log(err.message);
        }
        console.log('The file has been saved!');
    });

    file.mv('./uploads/'   filename, (err) => {
        if (err) {
            return res.status(500).send(err);
        }
        res.send('File uploaded!<br>'  
        '<a href="/file_uploading">Upload Another File</a><br>'  
        '<a href="/visualize_paragraphs">Visualize Paragraphs</a><br>'  
        '<a href="/tag_paragraphs">Tag Paragraphs</a>');
    });


    fs.readFile('./uploads/'   filename, {encoding: 'utf-8'}, (err, data) => {
        if (err) {
            return console.log(err.message);
        }
        let lines = data.split('\n');
        for (let i = 0; i < lines.length; i  ) {
            db.run('INSERT INTO paragraphs (text) VALUES (?)', [lines[i]], (err) => {
                if (err) {
                    return console.log(err.message);
                }
            });
        }
    });
});

app.get('/visualize_paragraphs', (req, res) => {
    db.all('SELECT * FROM paragraphs', (err, rows) => {
        if (err) {
            throw err;
        }
        rows.forEach((row) => {
            res.write('<h1>Visualize Paragraphs</h1>');
            res.write(row.text   '<br>');
        });
        res.end();
    });
});

app.get('/tag_paragraphs', (req, res) => {
    let paragraph_id = req.query.paragraph_id;
    let tag = req.query.tag;
    if (paragraph_id && tag) {
        db.run('UPDATE paragraphs SET tag = ? WHERE id = ?', [tag, paragraph_id], function (err) {
            if (err) {
                return console.log(err.message);
            }
            console.log(`Row(s) updated: ${this.changes}`);
        });
        res.send('<h1>Tag Paragraphs</h1>'  
            '<p>Paragraph '   paragraph_id   ' has been tagged as '   tag   '</p>');
    } else {
        db.all('SELECT * FROM paragraphs', (err, rows) => {
            if (err) {
                throw err;
            }
            res.write('<h1>Tag Paragraphs</h1>'  
                '<table>');
            rows.forEach((row) => {
                res.write('<tr><td>'   row.id   '</td><td>'   row.text   '</td></tr>');
            });
            res.write('</table>'  
                '<form action="/tag_paragraphs" method="get">'  
                '<label for="paragraph_id">Paragraph ID:</label>'  
                '<input type="text" id="paragraph_id" name="paragraph_id"><br>'  
                '<label for="tag">Tag:</label>'  
                '<input type="text" id="tag" name="tag"><br>'  
                '<input type="submit" value="Submit">'  
                '</form>');
            res.end();
        });
    }
});

app.listen(3000, () => {
    console.log('Example app listening on port 3000!');
});

Can you help me? What am I doing wrong?

Thank you very much in advance.


EDIT:

This is the solution and the fixed code.

const express = require('express');
const app = express();
const bodyParser = require('body-parser');
const fs = require('fs');
const sqlite3 = require('sqlite3').verbose();
const multer = require('multer');
const path = require('path');

// Set up multer
const storage = multer.diskStorage({
    destination: './uploads/',
    filename: function (req, file, cb) {
        cb(null, file.fieldname   '-'   Date.now()   path.extname(file.originalname));
    },
});

const upload = multer({
    storage,
    dest: './uploads/',
    limits: {
        fileSize: 1000000
    },
    fileFilter: function (req, file, cb) {
        checkFileType(file, cb);
    }
});

// Check if the file is a txt file
function checkFileType(file, cb) {
    const filetypes = /\.(txt)$/;
    const extname = filetypes.test(path.extname(file.originalname).toLowerCase());
    const mimetypes = 'text/plain'

    mimetype = mimetypes === file.mimetype;

    if (mimetype && extname) {
        return cb(null, true);
    } else {
        cb('Error: Only txt files are allowed!');
    }
}

// Set up express
app.use(express.static('public'));
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());

// Create directories if they don't exist
if (!fs.existsSync('./db')) {
    fs.mkdirSync('./db');
}
if (!fs.existsSync('./uploads')) {
    fs.mkdirSync('./uploads');
}

// Connect to the database
let db = new sqlite3.Database('./db/paragraphs.db', sqlite3.OPEN_READWRITE | sqlite3.OPEN_CREATE, (err) => {
    if (err) {
        console.error(err.message);
    }
    console.log('Connected to the paragraphs database.');
});

// Create the paragraphs table if it doesn't exist
db.run('CREATE TABLE IF NOT EXISTS paragraphs (id INTEGER PRIMARY KEY AUTOINCREMENT, text TEXT, tag TEXT)', (err) => {
    if (err) {
        console.error(err.message);
    }
    console.log('Created paragraphs table.');
});

// Home page
app.get('/', (req, res) => {
    res.sendFile(__dirname   '/index.html');
    /*
    res.write('<h1>Welcome to the Paragraphs App</h1>'  
        '<a href="/file_uploading">Upload a File</a><br>'  
        '<a href="/visualize_paragraphs">Visualize Paragraphs</a><br>'  
        '<a href="/tag_paragraphs">Tag Paragraphs</a>');
    res.end();
     */
});

app.get('/file_uploading', (req, res) => {
    res.sendFile(__dirname   '/file_uploading.html');
});

app.post('/upload_file', upload.single('filetoupload'), async (req, res) => {
    let filename = req.file.filename;

    res.send('File uploaded!<br>'  
        '<a href="/file_uploading">Upload Another File</a><br>'  
        '<a href="/visualize_paragraphs">Visualize Paragraphs</a><br>'  
        '<a href="/tag_paragraphs">Tag Paragraphs</a>');

    fs.readFile('./uploads/'   filename, {encoding: 'utf-8'}, (err, data) => {
        if (err) {
            return console.log(err.message);
        }
        let lines = data.split('\r\n');
        for (let i = 0; i < lines.length; i  ) {
            db.run('INSERT INTO paragraphs (text) VALUES (?)', [lines[i]], (err) => {
                if (err) {
                    return console.log(err.message);
                }
            });
        }
    });
});

app.get('/visualize_paragraphs', (req, res) => {
    db.all('SELECT * FROM paragraphs', (err, rows) => {
        if (err) {
            throw err;
        }
        rows.forEach((row) => {
            res.write('<h1>Visualize Paragraphs</h1>');
            res.write(row.text   '<br>');
        });
        res.end();
    });
});

app.get('/tag_paragraphs', (req, res) => {
    let paragraph_id = req.query.paragraph_id;
    let tag = req.query.tag;
    if (paragraph_id && tag) {
        db.run('UPDATE paragraphs SET tag = ? WHERE id = ?', [tag, paragraph_id], function (err) {
            if (err) {
                return console.log(err.message);
            }
            console.log(`Row(s) updated: ${this.changes}`);
        });
        res.send('<h1>Tag Paragraphs</h1>'  
            '<p>Paragraph '   paragraph_id   ' has been tagged as '   tag   '</p>');
    } else {
        db.all('SELECT * FROM paragraphs', (err, rows) => {
            if (err) {
                throw err;
            }
            res.write('<h1>Tag Paragraphs</h1>'  
                '<table>');
            rows.forEach((row) => {
                res.write('<tr><td>'   row.id   '</td><td>'   row.text   '</td></tr>');
            });
            res.write('</table>'  
                '<form action="/tag_paragraphs" method="get">'  
                '<label for="paragraph_id">Paragraph ID:</label>'  
                '<input type="text" id="paragraph_id" name="paragraph_id"><br>'  
                '<label for="tag">Tag:</label>'  
                '<input type="text" id="tag" name="tag"><br>'  
                '<input type="submit" value="Submit">'  
                '</form>');
            res.end();
        });
    }
});

app.listen(3000, () => {
    console.log('Example app listening on port 3000!');
});

CodePudding user response:

Try uploading file using Multer Middle ware it will ease out your life, I am attaching a sample code which I used in one of my Project

const express = require('express');
const fs = require('fs');
const Log = require('../utils/Log');
const User = require('../db/models/user_model');
const BandCode = require('../db/models/band_codes')
const UserRouter = new express.Router();
const Response = require('../const/Response');
const auth = require('../middleware/auth');
const path = require('path');
const multer = require('multer')
const sharp = require('sharp')
const appleReceiptVerify = require('node-apple-receipt-verify');
const validator = require('validator');
const { sendPasswordResetEmail } = require('../emails/account');
const { totp } = require('otplib');
const { isError } = require('util');
const key = process.env.TOTP;
totp.options = { step: 1800 }

var storage = multer.diskStorage({
    destination: (req, file, cb) => {
        cb(null, process.env.PUBLIC)
    },
    filename: (req, file, cb) => {
        
        cb(null, req.user._id   ''   Date.now()   path.extname(file.originalname))
    }
});


const upload = multer({
    storage,
    limits: {
        fileSize: 9000000
    },
    fileFilter(req, file, cb) {
        if (!file.originalname.match(/\.(jpg|jpeg|png)$/)) {
            return cb(new Error('Please upload an image'))
        }

        cb(undefined, true)
    }
})

UserRouter.post('/users/avatar', auth, upload.single('avatar'), async (req, res) => {
    console.log("User Image Update Request")
    const filepath = process.env.BASE_PATH   req.file.filename;
    console.log(filepath)
    req.user.imageUrl = filepath;
    req.user.avatar = null

    // const file = await sharp(req.file.buffer).resize({ width: 250, height: 250 }).png().toFile();
    // req.user.avatar = buffer
    await req.user.save()
    const user = req.user.toObject();
    delete user.avatar
    delete user.password
    delete user.token
    delete user.tokens
    delete user.socialId
    delete user.totop
    delete user.buffer
    delete user.__v
    const response = new Response("SUCCESS", "Image saved", 200, 0, { user });
    res.send(response)
}, (error, req, res, next) => {
    console.log(error);
    res.status(400).send({ error: error.message })
})


module.exports = UserRouter;

CodePudding user response:

From the documentation:

In Express 4, req.files is no longer available on the req object by default. To access uploaded files on the req.files object, use multipart-handling middleware like busboy, multer, formidable, multiparty, connect-multiparty, or pez.

… and you don't have any such middleware loaded.

CodePudding user response:

Ah, I have had the problem before.

It's probably the form type that's being sent by the client.

I would look into multer!

https://www.npmjs.com/package/multer

I think you'll find your solution with that package

CodePudding user response:

https://www.npmjs.com/package/multer

https://www.npmjs.com/package/busboy

see that the npm package, I think your problem solved with that package

CodePudding user response:

you have to use multer for file upload

router.post('/upload-file', upload.single('image'))


const multer = require('multer');
const storage = multer.diskStorage({
 destination: function(req, file, cb) {
    cb(null, './uploads');
 },
 filename: function (req, file, cb) {
    cb(null , `${Date.now().toString()}-${file.originalname}`);
 }
});

const upload = multer({ storage: storage, limits: { fieldSize: 10 * 1024 * 1024 } });
  • Related