Home > Software design >  How do I upload an image to diskStorage?
How do I upload an image to diskStorage?

Time:11-07

I have a for a signup where the user give me a: login, password and an image(profile pic). This is my form:

<fieldset>
    <legend><h1>Sign-Up</h1></legend>
    <form>
        <label htmlFor="login">Login</label>
        <input type="text" placeholder="Login" id="signup_name">
        <br>
        <label htmlFor="passwd">Password</label>
        <input type="password" placeholder="Password" id="signup_passwd">
        <br>
        <label for="imageFile">Image</label>
        <br>
        <input name="image" type="file" id="imageFile"/><br>
        <br>
        <button type="button" onclick="signup()">Submit</button>
    </form>
</fieldset>

The script takes the information and send it to the database, except for the image. As for the image, I want the server to store it on diskStorage, locally on a folder. I have a folder named "FCImages" where I want to store those images, this folder is located at /home/$user/project/server/FCImages (Linux). So my question is, how do I get this image from the , send it to the server, then the server store this image on that exact folder??? what ever the solution may be.

I tried:

const imgPath = document.getElementById("imageFile").files[0];
const reader = new FileReader();

reader.addEventListener("load", function () {
    // Convert file to base64 string and save to localStorage
    localStorage.setItem("image", reader.result);
}, false);

if (imgPath) {
    reader.readAsDataURL(imgPath);
}

but that is not what I want, I tried:

fs.writeFile();

couldn't figure it out, then I tried a NPM package - multer and this package is possible the answer I'm looking for but all the videos show the back-end code and not the front-end.

CodePudding user response:

To upload files using html or some client like postman you need to use this content-type: multipart/form-data

<form id="registerForm" 
action="/upload" method="POST" 
autocomplete="off" 
enctype="multipart/form-data">

enter image description here

enter image description here

And then in the nodejs backend, you need to set the multer with the exact input name used in the html, imageProfile in this example

app.post('/upload', upload.single('imageProfile'), function(req, res) {

Complete code here

app.js

const os = require('os');
const express = require('express');
const app = express();
const path = require('path')
const xssEscape = require('xss-escape');

const multer = require('multer');

var storage = multer.diskStorage({
  destination: function(req, file, cb) {
    cb(null, path.join(__dirname, "storage"))
  },
  filename: function(req, file, cb) {
    var originalname = xssEscape(file.originalname);
    cb(null, originalname)
  }
})

const upload = multer({
  storage: storage
});

app.post('/upload', upload.single('imageProfile'), function(req, res) {
  const imageProfile = req.file;
  console.log(imageProfile);
  console.log(JSON.stringify(req.body))
  res.send("Ok");
});

app.get('/', async function(req, res) {
  res.sendFile(path.join(__dirname,'index.html'));
});

app.listen(process.env.PORT || 5000, () => {
  console.log(`Server started at 5000`);
});

index.html

<!DOCTYPE html>
<html>
<head>
    <link rel="icon" href="data:,">
</head>
<body>
    <p>User registration</p>
    <form id="registerForm" action="/upload" method="POST" autocomplete="off" enctype="multipart/form-data">
        <label htmlFor="login">Username</label><br>
        <input type="text" id="username" name="username" />
        <br><br>
        <label htmlFor="login">Image profile</label><br>
        <input type="file" id="imageProfile" name="imageProfile" />
        <br><br>
        <input type="submit" value="Register" />
        <br><br>
        <div id="result" />
    </form>
</body>
</html>

package.json

"dependencies": {
    "express": "^4.18.1",
    "multer": "^1.4.5-lts.1",
    "supervisor": "^0.12.0",
    "xss-escape": "0.0.6"
}

Advice

  • Build a single nodejs in which the frontend (html) and the backend are in the same repository is just for small requirements. I advice you to develop a modern frontend with some spa(react/angular/vue) in one git repository and a microservice in another git repository
  • Split the user registration in two steps
  • Related