These days it is vital to spice up your web content with irrelevant photos. No one is going to read a bunch of boring words, without some fun graphics! And a technocrat like you isn't going to use FTP to upload custom images. You need a web UI to dynamically upload image files. On demand. When you demand it!
With Node.js and Express, it's easy to add a photo upload facility. The first step is to create a basic upload form, and what could be more basic than this?
This is the Upload form template: (I use the EJS template engine to render HTML)
<% layout('../layout') -%> <h1><%= title %></h1> <form accept-charset="UTF-8" action="/admin/upload/image" class="new_uploaded_image_file" enctype="multipart/form-data" id="new_uploaded_image_file" method="POST"> <div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="✓" /></div> <input id="uploaded_image_file_photo" name="uploaded_image_file" type="file" /> <br/><br/> <input name="commit" type="submit" value="Submit" /> </form>
Then use the following modules: formidable does form parsing. fs-extra provides filesystem access, and async orchestrates callbacks.
... var formidable = require('formidable'); var fs = require('fs-extra'); var async = require('async'); ...
There's nothing interesting about serving up the upload form:
function setupGet(app) { app.get('/admin/upload/image', function (req, res) { res.render('../views/upload/image', {title: 'Upload Image' }); }); }
All the interesting things happen when the photo is being uploaded. After accessing the uploaded file using formidable, that file needs to be copied from the temp folder to the destination folder, and then removed from the source folder. If you happen to know that the temp folder will always be on the same volume as the target folder, you could do a "move" rather than a "copy and delete". That is definitely not the case for my website, when it's deployed on the server.
Note, you could call synchronous copy and remove methods to manipulate the image file, but that defeats one of the strengths of Node.js: the ability to run massive amounts of IO in the background, rather than blocking on synchronous code. Plus, the async module makes it super-easy to handle the asynchronous callbacks. There's no reason to use those blocking calls.
function setupPostUploadImage(app) { app.post('/admin/upload/image', function (req, res) { global.logger.info('post image'); var form = new formidable.IncomingForm(); form.parse(req, function (error, fields, files) { if (!error) { var file = files["uploaded_image_file"]; async.series([ function (callback) { global.logger.info('copying image ' + file.path + ' to ./public/uploaded_images/'); fs.copy(file.path, './public/uploaded_images/' + file.name, function (error) { callback(error); }); }, function (callback) { fs.remove(file.path, function (error, removed) { callback(error, removed); }); } ], function (error, results) { if (!error) { res.redirect('/admin/upload/images'); } else { global.logger.error('Error uploading image: ' + error); res.redirect('/error?message=12'); } }); } }); }); }
On this website, only authorized users are allowed to upload photos. Only me, in fact. I recommend that you do the same thing, unless your website has a legitimate need to accept user-contributed files. You do not want to open your server's filesystem up to bad guys!
I'd really like a hamburger right now!
Title | Date |
.NET Public-Key (Asymmetric) Cryptography Demo | July 20, 2025 |
Raspberry Pi 3B+ Photo Frame | June 17, 2025 |
EBTCalc (Android) Version 1.53 is now available | May 19, 2024 |
Vault 3 Security Enhancements | October 24, 2023 |
Vault 3 is now available for Apple OSX M2 Mac Computers! | September 18, 2023 |
Vault (for Desktop) Version 0.77 Released | March 26, 2023 |
EBTCalc (Android) Version 1.44 is now available | October 12, 2021 |