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