Preface
I've always wanted to write this article, but I've been reviewing it for the sake of exams. I've delayed writing until now. I wrote a small project with node's express framework, which has the function of uploading pictures. Here's how to realize it (I use ejs)
thinking
- First of all, when the user clicks upload avatar to update the avatar, the avatar will be uploaded to a folder of the project (I am stored in the public/images/img of the project), and the image name will be renamed (can be named by time stamp).
- At the same time, the image is inserted into the user picturepath of the current user in the user table
- Then update the user's session, assign the path in the picture to the picture attribute in the session
- The src of < img > gets the picture value of the current user's session, and finally dynamically refreshes the page's image and changes it to the image uploaded by the user
Achieving results
Code
ejs section
<img class="nav-user-photo" src="<%= user.picture.replace(/public(\/.*)/, "$1") %>" alt="Photo" style="height: 40px;"/>
<form enctype="multipart/form-data" method="post" name="fileInfo">
<input type="file" accept="image/png,image/jpg" id="picUpload" name="file">
</form>
<button type="button" class="btn btn-primary" id="modifyPicV">Determine</button>
js part
document.querySelector('#modifyPicV').addEventListener('click', function () {
let formData = new FormData();
formData.append("file",$("input[name='file']")[0].files[0]);//Insert the file object into the formData object
console.log(formData.get('file'));
$.ajax({
url:'/modifyPic',
type:'post',
data: formData,
processData: false, // Do not process data
contentType: false, // Do not set content type
success:function () {
alert('success');
location.reload();
},
})
});
In the routing part, use formatible, which is a Node.js module for parsing form data, especially file upload
let express = require('express');
let router = express.Router();
let fs = require('fs');
let {User} = require('../data/db');
let formidable = require('formidable');
let cacheFolder = 'public/images/';//Placement path
router.post('/modifyPic', function (req, res, next) {
let userDirPath = cacheFolder + "Img";
if (!fs.existsSync(userDirPath)) {
fs.mkdirSync(userDirPath);//Create directory
}
let form = new formidable.IncomingForm(); //Create upload form
form.encoding = 'utf-8'; //Settings editing
form.uploadDir = userDirPath; //Set upload directory
form.keepExtensions = true; //Reserved suffix
form.maxFieldsSize = 2 * 1024 * 1024; //file size
form.type = true;
form.parse(req, function (err, fields, files) {
if (err) {
return res.json(err);
}
let extName = ''; //Suffix
switch (files.file.type) {
case 'image/pjpeg':
extName = 'jpg';
break;
case 'image/jpeg':
extName = 'jpg';
break;
case 'image/png':
extName = 'png';
break;
case 'image/x-png':
extName = 'png';
break;
}
if (extName.length === 0) {
return res.json({
msg: 'Only supported png and jpg Format picture'
});
} else {
let avatarName = '/' + Date.now() + '.' + extName;
let newPath = form.uploadDir + avatarName;
fs.renameSync(files.file.path, newPath); //rename
console.log(newPath)
//Update table
User.update({
picture: newPath
}, {
where: {
username: req.session.user.username
}
}).then(function (data) {
if (data[0] !== undefined) {
User.findAll({
where: {
username: req.session.user.username
}
}).then(function (data) {
if (data[0] !== undefined) {
req.session.user.picture = data[0].dataValues.picture;
res.send(true);
} else {
res.send(false);
}
})
}
}).catch(function (err) {
console.log(err);
});
}
});
});