Reputation: 2304
Say I have this <input type="file" id="theFile">
I access the selected file with with myVar =
document.getElementById('theFile').value
The output is console.log(myVar); // C:\fakepath\xxx.txt
Then I do a simple POST, there are many ways to do a POST but one basic JavaScript way is:
var http = new XMLHttpRequest();
http.onreadystatechange = function() {
http.open("POST", "http://localhost:port/upload-test");
http.setRequestHeader('Content-type', 'application/json');
var body = {
file: document.getElementById('theFile').value
}
http.send(JSON.stringify(body));
Then in my Nodejs Express
service I do this:
app.post('/upload-test', (request, response) => {
console.log(request.body); // { file: 'C:\\fakepath\\xxx.txt' }
});
Now how do I save that file to the pc the service is running on?
I know of other solutions like https://www.w3schools.com/nodejs/nodejs_uploadfiles.asp but this requires the user to use a <form>
which is not what I want. I want to upload a file using a basic POST and JSON approach.
Upvotes: 1
Views: 1171
Reputation: 31
You can use Multer module for file upload
const multer = require('multer');
Now set destinatoin folder to save the upladed files
const upload = multer({ dest: './uploads/' });
finally use upload.single() for single file upload or upload.array() for multiple file uploads
app.post('/upload-test',upload.single('myFile'),(request, response) => {
console.log(request.body);
});
Upvotes: 0
Reputation: 1454
Client Side Firstly, you need to 'read' the file contents into a variable. You cannot upload a file directly as mentioned elsewhere on here.
I'm not sure what you're using client-side. E.g. React, Angular or plain Javascript. So, here's a link to another article on SO about how to select a client-side file and read its content into a var. Read Client-Side file
Once you have the file content in a var, you can 'post' that. E.g.
// Build the Headers object.
let headers = new Headers();
headers.append("Content-Type","application/json");
// Build the body object.
let body = {
fileName: varContainingFileName,
fileContent: varContianingContentsOfFile
};
// Build the request
const response = await fetch(URL, {method: 'POST',
headers:headers,
body:JSON.stringify(body)});
// See what we get back from the service. Note, for the await to work,
// Needs to be wrapped in async method.
console.log(response);
Server-Side I'm assuming you have set up your route for the API, so straight in....
const fs = require('fs');
uploadFile(req, res) {
const requestBody = JSON.parse(req.body);
log.info("Received File Upload request. File " + requestBody.fileName);
// If one doesn't exist, create a folder for the file
fs.existsSync("./SomeFolder/") || fs.mkdirSync("./SomeFolder/");
// Using method.then(otherMethod) with promises.
writeSourceDataToFile (requestBody.fileName,
"./SomeFolder/",
requestBody.fileContent)
.then(v => finalMethod(v, requestBody.fileName, "./SomeFolder/", res))
.catch(err => returnError(res, err) );
}
function writeSourceDataToFile (fileName, path, content) {
return new Promise((resolve, reject) => {
// User fs write stream to stream the file content var to file.
let writeSource = fs.createWriteStream(path + fileName)
.on('end', function () {
log.info("File wrote to disk - End event");
resolve (true);
})
.on('finish', function () {
log.info("File wrote to disk - Finish event");
resolve (true);
})
.on('error', function (err) {
log.info('Error whilst writing file - ' + fileName);
reject (err);
});
writeSource.write(content);
writeSource.end();
});
}
function finalMethod(v, fileName, path, res) {
// Final method just wraps things up and sends some message back to
// client.
log.info(fileName + " File Upload Process Completed.");
res.write("File Upload Process Completed.\n");
res.status(200).end();
}
// Something went wrong, log it and tell the client.
function returnError(res, err) {
log.error(err);
res.status(500).send(err);
}
Upvotes: 0
Reputation: 1347
The content-type of the request should be multipart/form-data, cos you are uploading the file. you can use multerjs for nodejs upload
var express = require('express')
var multer = require('multer')
var upload = multer({ dest: 'uploads/' })
var app = express()
app.post('/upload-test', upload.single('avatar'), function (req, res, next) {
// req.file is the `avatar` file
// req.body will hold the text fields, if there were any
})
Upvotes: 1