I am trying to compress an uploaded file using nodejs zlib.The compression works but trying to uncompress it throws an error.I created a compress route which is a post request to upload the file to be compressed:
app.post('/compress', upload.single('file'), (req, res) => {
try {
var streamInstance = new stream.Readable();
const destination = createWriteStream(`compressed/${req.file.originalname}.gz`);
const source = streamInstance.push(Buffer.from(JSON.stringify(req.file)))
res.json(source)
streamInstance.push(null);
pipeline(source, gzip, destination, (err, file) => {
if (err) {
console.log(err)
return res.json('An error occurred:', err);
} else {
console.log({
file: file
})
return res.json(file)
}
})
} catch (err) {
console.log(err)
res.json(err)
}
})
This add the compressed file in the compressed directory but trying to uncompress it throws an error.
Is there another method i could use in compressing this file using zlib?
Multer gives the ability to use the memoryStorage method.So you can get the actual buffer of that file.With that you can use this:
var storage = multer.memoryStorage()
var upload = multer({
storage: storage
})
app.post('/compress', upload.single('file'), async (req, res) => {
try {
const destination = `compressed/${req.file.originalname}.gz`;
await zlib.gzip(req.file.buffer, async (err, response) => {
if (err) {
return res.status(500).json({error:err})
} else {
await fs.appendFile(path.join(__dirname,destination), response, (err, data) => {
if (err) {
return res.status(500).json({error:err})
} else {
res.download(path.join(__dirname,destination),`${req.file.originalname}.gz`);
}
})
}
})
} catch (err) {
console.log(err)
res.json(err)
}
})
Related
I am trying to upload an image from my front end to the backend but it it doesn't send the image in the request
It says that the formdata is empty and it says that there's no image found, where is the problem and how can I fix this error?
Here is the code from the Frontend made in react:
const [userInfo, setuserInfo] = useState({
file:[],
filepreview:null,
});
const handleInputChange = (event) => {
setuserInfo({
...userInfo,
file:event.target.files[0],
filepreview:URL.createObjectURL(event.target.files[0]),
});
}
const [isSucces, setSuccess] = useState(null);
const submit = async () =>{
const formdata = new FormData();
formdata.append('avatar', userInfo.file);
console.log(formdata)
Axios.post("http://localhost:4000/imageupload", formdata,{
headers: { "Content-Type": "multipart/form-data" }
})
.then(res => { // then print response status
console.warn(res);
if(res.data.success === 1){
setSuccess("Image upload successfully");
}
})
}
The code of the Backend made in NodeJS:
const storage = multer.diskStorage({
destination: path.join(__dirname, './temp', 'uploads'),
filename: function (req, file, cb) {
// null as first argument means no error
cb(null, Date.now() + '-' + file.originalname )
}
})
app.post('/imageupload', async (req, res) => {
try {
// 'avatar' is the name of our file input field in the HTML form
let upload = multer({ storage: storage}).single('avatar');
upload(req, res, function(err) {
// req.file contains information of uploaded file
// req.body contains information of text fields
if (!req.file) {
return res.send('Please select an image to upload');
}
else if (err instanceof multer.MulterError) {
return res.send(err);
}
else if (err) {
return res.send(err);
}
const classifiedsadd = {
image: req.file.filename
};
res.send("ok")
});
}catch (err) {console.log(err)}
})
Edit:
Multer is essentially a nodejs router,i.e. a function that can be pipelined between your HTTP request and HTTP response.
I think that you should first make multer analyze your HTTP content and to actually populate the req.file before actually evaluate express parsers do their job.
const storage = multer.diskStorage({
destination: path.join(__dirname, './temp', 'uploads'),
filename: function (req, file, cb) {
// null as first argument means no error
cb(null, Date.now() + '-' + file.originalname )
}
})
let upload = multer({ storage: storage});
app.post('/imageupload', upload.single('avatar'), async (req, res) => {
try {
// 'avatar' is the name of our file input field in the HTML form
// req.file contains information of uploaded file
// req.body contains information of text fields
if (!req.file) {
return res.send('Please select an image to upload');
}
else if (err instanceof multer.MulterError) {
return res.send(err);
}
else if (err) {
return res.send(err);
}
const classifiedsadd = {
image: req.file.filename
};
res.send("ok")
}catch (err) {console.log(err)}
})
I am assuming that your upload code is working. Have you tried to read the HTTP request from your browser to see that the image has been correctly attached to the request?
Because probably the issue lies in the fact that you are not actually parsing the image.
const file = new File(userInfo.file, "avatar.png", {
type: 'image/png' // choose the appropriate
});
const formdata = new FormData();
formdata.append('avatar', file);
console.log(formdata)
I'm having troubles saving an incoming webm blob to the server. I'm using react-video-recorder on NextJS like this:
<VideoRecorder
onRecordingComplete={(videoBlob) => {
// Do something with the video...
fetch("/api/video",
method: "post",
body: videoBlob,
})
.then(function (response) {
console.log("done");
return response;
})
.catch(function (err) {
console.log('error', err);
});
console.log(url);
// output: blob:http://localhost:3000/99a5b711-f3d5-481d-9e04-8981d1be3727
console.log(videoBlob);
// output BlobĀ {size: 307028, type: "video/webm;codecs="vp8,opus""}
}}
/>
On the api side I'm trying to save the file like this. It does save something, but is only the first chunk or buffer. How can I capture and write the file to my server?
export default async (req, res) => {
fs.writeFile('test.webm', req.body, function (err) {
if (err) return console.log(err);
console.log('video saved');
} );
}
I did that task by doing this.
I saved the recordingChunks/Video blob to a state and then sent it to the Nodejs server from Reactjs Frontend
FrontEnd code:-
const blob = new Blob(context.data.recordedChunks, {
type: "video/webm",
});
const fd = new FormData()
fd.append('video', blob)
axios.post(`${process.env.REACT_APP_BASE_URL}/video/blob_video`, fd)
.then((res) => console.log(res.data))
.catch((err) => console.log(err))
Backend code:-
router.post('/blob_video', async (req, res) => {
try {
if (req.files.video !== undefined) {
const video = req.files.video // this is your file do what ever you want with it
const videoname = Date.now() + req.files.video.name + ".webm"
video.mv(`${__dirname}/../your_path/${videoname}`, err => {
if (err) {
console.log(err)
return res.json({ err })
}
})
}
res.json(req.body)
} catch (err) {
res.json({ success: false, err: err, msg: "Server error" })
console.log(err)
}
})
Using express-fileupload to upload a file you can do it with your favourite one.
I am creating a React and Node application, and at the moment I need to upload a PDF file, the code works well, but I was wondering how to use front variables to create the file name by multer.
The code...
Front:
const handleSubmit = async (e) => {
const dado = new FormData()
const year = data.split("/")
const dd = year[0];
const mm = year[1];
const aaaa = year[2];
dado.append('file', file)
dado.append('uni', uni)
dado.append('dd', dd)
dado.append('mm', mm)
dado.append('aaaa', aaaa)
console.log(dado)
axios.post("http://localhost:8080/api/comprebem/file", dado, {
})
.then(res => {
console.log(res.statusText)
})
}
Back:
const storage = multer.diskStorage({
destination:"../login/public/comprebem/ibama/",
filename: function (req, file, cb) {
console.log(file);
cb(null, `unidade${"req['uni']"}_data${file.originalname}` )
}
})
const upload = multer({ storage: storage }).single('file')
app.post('/api/comprebem/file',function(req, res) {
upload(req, res, function (err) {
if (err instanceof multer.MulterError) {
return res.status(500).json(err)
} else if (err) {
return res.status(500).json(err)
}
return res.status(200).send(req.file)
})
});
I'm a newbie trying to learn Nodejs. I've been trying to resolve an issue using an NPM module called Multer. I can't seem to write the right code to delete a User's image file or overwrite if the user uploads another one. Sorry for the inconvenience. Please help
My Delete Route works perfectly deleting both the "Posts" and "Image". However, my edit Route gives the below error
{"Error":{"errno":-4058,"syscall":"unlink","code":"ENOENT","path":"C:\cms\public\uploads\image-1568050604308.png"}}
const publicUploads = path.join(__dirname, '../../../public/uploads/');
const storage =
multer.diskStorage({
destination: publicUploads,
filename(req, file, cb){
cb(null,`${file.fieldname}-${Date.now()}${path.extname(file.originalname)}`)
}
});
const upload = multer({
storage,
limits: {
fileSize: 1000000
},
fileFilter(req, file, cb){
if(!file.originalname.match(/\.(jpeg|jpg|png)$/)){
return cb(new Error('Please upload an image file'))
}
cb(null, true)
}
})
router.put('/admin/posts/edit/:id', upload.single('image'), async (req, res) => {
const updates = Object.keys(req.body);
const allowedUpdates = ['title', 'body', 'status', 'image', 'allowComments'];
const isValid = updates.every(update => allowedUpdates.includes(update));
if(!isValid){
return res.send({Error: 'Invalid Update'})
}
try {
const post = await Post.findOne({_id: req.params.id});
if(!post){
return res.send({Error: 'Could not find your post'})
}
if(req.file){
fs.unlinkSync(`${publicUploads}${post.image}`);
post.image = req.file.filename
}
updates.forEach(update => {
post[update] = req.body[update]
})
post.allowComments = req.body.allowComments === 'on'? true:false;
await post.save();
req.flash('notice', 'Your post was edited successfully!')
res.status(200).redirect('/admin/posts')
} catch (error) {
res.send({Error: error})
}
}, (error, req, res, next) => {
res.send({Error: error})
})
You can delete the image natively with the Node package "fs". You don't need to use Multer for this:
// Remove old photo
if (oldPhoto) {
const oldPath = path.join(__dirname, "..", "images", oldPhoto);
if (fs.existsSync(oldPath)) {
fs.unlink(oldPath, (err) => {
if (err) {
console.error(err);
return;
}
res.status(200).send(userObj);
});
}
}
can you please tell me, what i doing wrong, when try to upload image to cloudinary?
app.js
I don't need to store images on server, so i store it in memory.
var cloudinary = require('cloudinary');
cloudinary.config({
cloud_name: 'hidden',
api_key: 'hidden',
api_secret: 'hidden'
});
var multer = require('multer');
var storage = multer.memoryStorage()
var upload = multer({ storage: storage })
Site form (jade/pug)
form(action="/?_csrf="+csrfToken method="post" enctype='multipart/form-data')
input(type="file" name="avatar")
input(type="submit" value="upload")
App post
app.post('/', upload.single('avatar'), function(req, res, next){
console.log('Should be undefined:', req.file.path); //yes
console.log('Should be the buffer:', req.file.buffer); //yes
cloudinary.uploader.upload(req.file.path, function(result) { console.log(result) });
});
and i get error
{ error: { message: 'Missing required parameter - file', http_code: 400 } }
i find out how (just use Datauri):
var dUri = new Datauri();
dUri.format(path.extname('TEST').toString(), req.file.buffer);
cloudinary.uploader.upload(dUri.content, function (err, result) {
if (err) {
console.log(err);
} else {
console.log(result);
}
});
I wasnt able to upload directly from my form to server but i used a trick first i stored files on disk then try to upload my file.
i use heroku hosting it means my files will be delete after 30 min. it means i will not have any storage problem.
//#1 i collect data into storage ./image/filename
await file.mv('./image/' + filename, async (err) => {
if (err) {
console.log("server'/upload' : faild to upload error =>" + err)
res.send('Save files => error : ' + err)
}
else {
try {
const client = await pool.connect()
//await client.query(`INSERT INTO test_table(id, name) VALUES(${1},'${"test"}')`)
const result = await client.query(`INSERT into post(musicname,artistname,price, music, picture)
VALUES ('${textName}','${textArtist}','${textPrice}', '${musicname}','${filename}')`);
res.send("server'/upload' : inserting new Data is Done.")
console.log("server'/upload' : inserting new Data is Done.")
client.release();
} catch (err) {
console.error(err);
res.send("Error " + err);
}
}
})
await fileMusic.mv('./music/' + musicname, (err) => {
if (err) {
console.log(err)
res.send('save files => error')
}
})
//#2 uplaoding collected data into cloudinary
await cloudinary.v2.uploader.upload('./image/' + filename, {public_id: `${filename}`},
function(error, result){
result;
console.log(result.url, error)
});