- Getting Started
- Browser Support
- Languages Support
- Shortcuts
- Activation
- Examples
- Customize the Editor
- Use-cases
- Plugins
- APIs
- Development Frameworks
- Server Integrations
- Server SDKs
- Migration Guides
- Changelog
- Tutorials
Node.JS
File Upload
The following sections describe how to handle file uploads on your server using Node.JS as a server-side language. For information on the upload workflow refer to the file upload documentation.
Dependencies
The node.JS file upload example requires the following dependencies:
- Using npm you need package.json
- Using bower you need bower.json
Make sure that you run npm install
, or if you are using bower run bower install
Frontend
Setting up the index page.
- On the
head
section include the Editor style. - On the
body
section include the Editor JS files and define the area for the editor. - Initialize the editor and set the file upload URL
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link href="https://cdn.jsdelivr.net/npm/froala-editor@latest/css/froala_editor.pkgd.min.css" rel="stylesheet" type="text/css" />
</head>
<body>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/froala-editor@latest/js/froala_editor.pkgd.min.js"></script>
<div class="sample">
<h2>File upload example.</h2>
<form>
<textarea id="edit" name="content"></textarea>
</form>
</div>
<script>
new FroalaEditor('#edit', {
// Set the file upload URL.
fileUploadURL: '/UploadFiles',
fileUploadParams: {
id: 'my_editor'
}
})
</script>
</body>
</html>
The full code should look like this:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link href="https://cdn.jsdelivr.net/npm/froala-editor@latest/css/froala_editor.pkgd.min.css" rel="stylesheet" type="text/css" />
</head>
<body>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/froala-editor@latest/js/froala_editor.pkgd.min.js"></script>
<div class="sample">
<h2>File upload example.</h2>
<form>
<textarea id="edit" name="content"></textarea>
</form>
</div>
<script>
new FroalaEditor('#edit', {
fileUploadURL: '/UploadFiles',
fileUploadParams: {
id: 'my_editor'
}
})
</script>
</body>
</html>
Backend
server.js
handles the server part for Node.JS
server.js handles both image and file upload
// Include required libs
var express = require("express");
var app = express();
var bodyParser = require("body-parser")
var path = require("path");
var fs = require("fs");
var upload_file = require("./file_upload.js");
var upload_image = require("./image_upload.js");
app.use(express.static(__dirname + "/"));
app.use(bodyParser.urlencoded({ extended: false }));
app.get("/", function(req, res) {
res.sendFile(__dirname + "/index.html");
});
// File POST handler.
app.post("/file_upload", function (req, res) {
upload_file(req, function(err, data) {
if (err) {
return res.status(404).end(JSON.stringify(err));
}
res.send(data);
});
});
// Image POST handler.
app.post("/image_upload", function (req, res) {
upload_image(req, function(err, data) {
if (err) {
return res.status(404).end(JSON.stringify(err));
}
res.send(data);
});
});
// Create folder for uploading files.
var filesDir = path.join(path.dirname(require.main.filename), "uploads");
if (!fs.existsSync(filesDir)){
fs.mkdirSync(filesDir);
}
// Init server.
app.listen(3000, function () {
console.log("Example app listening on port 3000!");
});
file_upload.js
handles the upload part. It has basic file format validations that can be easily extended.
The uploads directory must be set to a valid location before making uploads. The path can be any folder that is accessible and writable.
If the uploaded file passes the validation step, the server responds with a JSON object containing a link to the uploaded file.
E.g.: {"link":"http://server_address/uploads/name_of_file"}
var Busboy = require("busboy");
var path = require("path");
var fs = require("fs");
var sha1 = require("sha1");
// Gets a filename extension.
function getExtension(filename) {
return filename.split(".").pop();
}
// Test if a file is valid based on its extension and mime type.
function isFileValid(filename, mimetype) {
var allowedExts = ["txt", "pdf", "doc"];
var allowedMimeTypes = ["text/plain", "application/msword", "application/x-pdf", "application/pdf"];
// Get file extension.
var extension = getExtension(filename);
return allowedExts.indexOf(extension.toLowerCase()) != -1 &&
allowedMimeTypes.indexOf(mimetype) != -1;
}
function upload (req, callback) {
// The route on which the file is saved.
var fileRoute = "/uploads/";
// Server side file path on which the file is saved.
var saveToPath = null;
// Flag to tell if a stream had an error.
var hadStreamError = null;
// Used for sending response.
var link = null;
// Stream error handler.
function handleStreamError(error) {
// Do not enter twice in here.
if (hadStreamError) {
return;
}
hadStreamError = error;
// Cleanup: delete the saved path.
if (saveToPath) {
return fs.unlink(saveToPath, function (err) {
return callback(error);
});
}
return callback(error);
}
// Instantiate Busboy.
try {
var busboy = new Busboy({ headers: req.headers });
} catch(e) {
return callback(e);
}
// Handle file arrival.
busboy.on("file", function(fieldname, file, filename, encoding, mimetype) {
// Check fieldname:
if ("file" != fieldname) {
// Stop receiving from this stream.
file.resume();
return callback("Fieldname is not correct. It must be "file".");
}
// Generate link.
var randomName = sha1(new Date().getTime()) + "." + getExtension(filename);
link = fileRoute + randomName;
// Generate path where the file will be saved.
var appDir = path.dirname(require.main.filename);
saveToPath = path.join(appDir, link);
// Pipe reader stream (file from client) into writer stream (file from disk).
file.on("error", handleStreamError);
// Create stream writer to save to file to disk.
var diskWriterStream = fs.createWriteStream(saveToPath);
diskWriterStream.on("error", handleStreamError);
// Validate file after it is successfully saved to disk.
diskWriterStream.on("finish", function() {
// Check if file is valid
var status = isFileValid(saveToPath, mimetype);
if (!status) {
return handleStreamError("File does not meet the validation.");
}
return callback(null, {link: link});
});
// Save file to disk.
file.pipe(diskWriterStream);
});
// Handle file upload termination.
busboy.on("error", handleStreamError);
req.on("error", handleStreamError);
// Pipe reader stream into writer stream.
return req.pipe(busboy);
}
module.exports = upload;
Do you think we can improve this article? Let us know.