I'm working on creating a simple file uploader on a node server with expressjs as the middleware. So far, the server side looks like:
app.post('/upload', function(req, res) {
console.log(req.files);
//Handle the file
fs.readFile(req.files.imageUploader.path, function(err, data) {
var newPath = __dirname;
console.log(newPath);
console.log(data);
fs.writeFile(newPath, data, function(err) {
console.log(err);
res.send("AOK");
});
});
});
Now, the log statement for __dirname is my source directory, as expected (C:\Development\GitHub\ExpressFileUpload), however an error is happening on the upload:
{ [Error: EISDIR, open 'C:\Development\GitHub\ExpressFileUpload']
errno: 28,
code: 'EISDIR',
path: 'C:\\Development\\GitHub\\ExpressFileUpload' }
I've tried changing the newPath to be / and ./ but no change, different errors, but still errors. Is it something to do with the double \\ in the path in the error? Am I missing something simple here? Thanks for the help, let me know if more info is needed.
The __dirname global object is a directory, not a file. Therefore, you can't open it for writing, which is what fs.writeFile() attempts to do in your script, hence the reason you are getting a EISDIR. Assuming you want the file to be written with the same name it was uploaded with, you can do this:
var file = req.files.imageUploader;
fs.readFile(file.path, function(err, data) {
var path = __dirname + '/' + file.name;
fs.writeFile(path, data, function(err) {
});
});
Related
I am building an Electron application and I have a logs.txt file which I want to read the contents of and put it on an HTML page. I'm using NodeJS and the "fs" module but the following code is giving me the error "Uncaught Error: ENOENT: no such file or directory..."
I think the issue may lie in the reference of it. Here's the code below:
const fs = require('fs')
fs.readFile('file://' + __dirname + '/logs.txt', function(err, data) {
if (err) throw err;
document.getElementById("main").innerHTML = data;
});
In the error it shows me the exact location of the file. Here's the error I'm getting:
Uncaught Error: ENOENT: no such file or directory, open 'file:///Users/MY_USER_ACCOUNT/files/code/git/MY_APP/src/usr/logs.txt'
This is exactly where the logs.txt file is, but for some reason it still says that there's no such file there.
I'm on a Mac if that is relevant.
Thank you.
Use a path, not a URL
fs.readFile expects a file path if passed a string as argument.
You’re passing it a file:// URL string instead. Remove file://.
Pass the file’s content encoding
You also want to pass the file’s encoding to fs.readFile:
const fs = require('fs')
fs.readFile(__dirname + '/logs.txt', 'utf-8', function(err, data) {
if (err) throw err;
document.getElementById("main").innerHTML = data;
});
(Are you sure you want to read logs.txt relative to the location of your JavaScript source file?)
Use Promises
const fsPromises = require('fs').promises;
const data = await fs.readFile(__dirname + '/logs.txt', 'utf-8')
document.getElementById("main").innerHTML = data;
If you are using the file:// format, you need to create a URL object to pass to fs.readFile() like this rather than just passing it as a string:
const fileUrl = new URL('file://' + __dirname + '/logs.txt');
fs.readFile(fileUrl, function(err, data) {
if (err) throw err;
document.getElementById("main").innerHTML = data;
});
See the documentation here
I am working on image upload via nodejs and multer module and this is the code im using:
app.post('/upload', upload.single('file'), function(req, res, next) {
var tmp_path = req.file.path,
target_path = __dirname + '/public/uploads/' + req.file.originalname,
src = fs.createReadStream(tmp_path),
dest = fs.createWriteStream(target_path);
src.pipe(dest);
fs.unlink(tmp_path); //deleting the tmp_path
src.on('end', function() {
res.json({
success: true,
file: '/uploads/' + req.file.originalname
});
});
src.on('error', function(err) {
console.log('err', err);
res.json({
success: false
});
});
});
The problem is that sometimes (it occures randomly) error callback is triggered, with this contents:
So it looks like additional slashes are added to the path which causes script not to find temp location and returns error, maybe someone encountered this problem and can help ;)
You can use the following code in order to get rid of this error...
try:- path.replace("\\","/");
This will definitely solve your problem.
Try running the unlink after success message is sent, pipe is asynchronous so might be executing after the delete.
src.on('end', function() {
res.json({
success: true,
file: '/uploads/' + req.file.originalname
});
fs.unlink(tmp_path)
});
I'm allowing users to upload files and would like to know if it is possible to only allow the user who uploaded their files access to it.
Currently I am just uploading these to a static folder (Public).
Simply put a route to render the file (this will decrease performance)
Save the file as : filename.extension.userid in a non public folder for example a directory named upload.
Put a route to catch the request on the directory upload :
app.get("/upload/:filename", function(req, res){
var fname = req.params.filename;
var userid = req.user.id; // RETRIEVE AUTHENTICATED USER ID
var fullname = fname+"."+userid;
fs.readFile(__dirname+"/../public/upload/"+fullname, 'base64', function(err, data){
if(err || !data) return res.status(404);
res.set('Content-Disposition', 'attachment; filename="'+fname+'"');
res.set('Content-Type', 'application/pdf'); // example for pdf
return res.end(data, 'base64');
});
});
I couldn't find a reason why you were suggesting using another route to handle the upload. I was able to post to the same route. All that I needed to do was include the path and set it accordingly.
var folder = newPath = path.join(__dirname, '..', './uploads')
var newPath = folder + '/' + callback.fileName;
fs.writeFile(newPath, data, function(err) {
if (err) {
console.log(err)
} else {
//Do stuff
}
});
After the file was uploaded I was then able to complete my task.
I'm trying to find an answer to this question for a long time: I need to upload a text/html file through my Node.Js express app and to save its contents into a variable for further treatment.
I can make the multipart form, of course, and post the content, but what I can access so far is only req.files which contains information about the file, but not the actual contents.
How do I get the actual text/html contents from the file?
I don't want to save it to my server, just pass on the content to my app and get rid of the file, so I don't want to use a module like formidable.
Can anyone help please?
Thank you!
The file is saved by default in a temporary folder (likely /tmp). You need to open the file, read its contents, and then delete it.
You'll want to use this API: http://nodejs.org/api/fs.html
And you could do this:
fs = require('fs');
fs.readFile(req.files.path, function (err, data) {
if (err) throw err;
// data will contain your file contents
console.log(data)
// delete file
fs.unlink(req.files.path, function (err) {
if (err) throw err;
console.log('successfully deleted ' + req.files.path);
});
});
Use multer https://github.com/expressjs/multer with the option inMemory: true.
As a crude example you'll want to do something like this.
app.post('test', function(req, res, next) {
var result = '';
multer({
inMemory: true,
onFileUploadData: function(file, data) {
result += data;
},
onFileUploadComplete: function(file) {
console.log(result); // This is what you want
}
})(req, res, next);
});
sorry, very new to Node.js here. I am having trouble getting my head around a good strategy to upload files from an iphone client into a node.js server and storing it on the server side.
For now, I can accept a binary file on the server and save it to the filesystem with the following code:
app.post('/upload', function(req, res){
// get the temporary location of the file
var tmp_path = req.files.pic.path;
// set where the file should actually exists - in this case it is in the "images" directory
var target_path = './uploads/' + req.files.pic.name;
// move the file from the temporary location to the intended location
fs.rename(tmp_path, target_path, function(err) {
if (err) throw err;
// delete the temporary file, so that the explicitly set temporary upload dir does not get filled with unwanted files
fs.unlink(tmp_path, function() {
if (err) throw err;
res.send('File uploaded to: ' + target_path + ' - ' + req.files.pic.size + ' bytes');
});
});
console.log(req.files.pic.name);
res.send('DONE', 200);
res.end();
});
With this code, I first accept a multipart form upload of a jpeg from the iphone into the /tmp directory, then I rename and move the file to the ./uploads directory. My problem is how to save this file into the DB.
From what I've read, I have three choices (I think!)
Save the files to some upload directory and store the local path into the mongodb for later access
Save the file itself into MongoDb with a Buffer
Use grid-fs to save the file.
I have been trying #3 using this module I found called gridfs-stream (Since I am using mongoose), but I really don't understand the source code in the package.
My question is a two-parter: Among the 3 choices above, would #3 indeed be the way to go? If so, I really need some help on understanding how to use gridfs-stream.
I know the following code is wrong, but this is my attempt thus far to see if I can slot it into my existing upload code:
app.post('/upload', function(req, res){
// get the temporary location of the file
var tmp_path = req.files.pic.path;
// set where the file should actually exists - in this case it is in the "images" directory
var target_path = './uploads/' + req.files.pic.name;
// move the file from the temporary location to the intended location
fs.rename(tmp_path, target_path, function(err) {
if (err) throw err;
var conn = mongoose.createConnection('localhost', 'myahkvoicedb');
conn.once('open', function () {
var gfs = Grid(conn.db, mongoose.mongo);
// all set!
var writestream = gfs.createWriteStream('req.files.pic.name');
fs.createReadStream('./uploads/').pipe(writestream);
/* // APP CRASHES HERE WITH THE FOLLOWING:
stream.js:81
throw er; // Unhandled stream error in pipe.
^
Error: EISDIR, read
*/
})
// delete the temporary file, so that the explicitly set temporary upload dir does not get filled with unwanted files
fs.unlink(tmp_path, function() {
if (err) throw err;
res.send('File uploaded to: ' + target_path + ' - ' + req.files.pic.size + ' bytes');
});
});
console.log(req.files.pic.name);
res.send('DONE', 200);
res.end();
});
Any help would be appreciated. Thank you!