My code in not functioning sometimes.
here is my Upload.jsx
function FileUpload() {
const [file, setFile] = useState();
const handleSubmit = (e) => {
e.preventDefault();
const formData = new FormData();
formData.append("file", file);
axios
.post("http://localhost:5000/form", formData)
.then((res) => console.log(res.data))
.catch((err) => console.log(err));
};
return (
<Form onSubmit={handleSubmit}>
<Form.Group controlId="formFile" className="mb-3">
<Form.Label>Default file input example</Form.Label>
<Form.Control
type="file"
onChange={(e) => setFile(e.target.files[0])}
/>
<Button variant="primary" type="submit">
Submit
</Button>
</Form.Group>
</Form>
);
}
and here is my app.js
const fileupload = require('express-fileupload')
app.use(express.json({limit:'5000mb'}));
app.use(express.urlencoded({ extended: false, limit:'5000mb', parameterLimit:50000000 }));
app.post("/form", (req, res) => {
fs.writeFile(req.files.file.name, req.files.file.data, (err)=>{
err && console.log(err);
!err && console.log('completed');
})
})
Everything is fine when I am uploading any other files excepts json file. File size doesn't matter. I am able to upload 900mb of file without any issue.
the problem is when I am uploading a json file size of 250mb(or any sized) only, its missing data and saved to the server only 12mb - 35mb(randomly sized).
And sometimes fully uploaded and saved without any missing data.
I don't understand what I am missing
Please help. Thanks is advance.
Can you please send the response back to the application from the server and give a try like this
const fileupload = require('express-fileupload')
app.use(express.json({limit:'5000mb'}));
app.use(express.urlencoded({ extended: false, limit:'5000mb', parameterLimit:50000000 }));
app.post("/form", (req, res) => {
fs.writeFile(req.files.file.name, req.files.file.data, (err)=>{
if(err){
console.log(err);
res.status(500).send(err);
return
}
console.log('completed');
res.status(200).send('ok');
})
})
Related
I have stored the file after uploading it to the downloads folder in my project directory.
I want to download that saved file from the frontend.
When I click on the download button, it doesn't fetch the file.
And when I go to http://localhost:5000/download on the express app, I got this error message
Error: Can't set headers after they are sent.
Express Server Code:
app.get('/download', (req, res) => {
res.send('file downloaded')
const file = './downloads/output.yml';
res.download(file, 'openapi.yml', (err) => {
if (err) {
console.log(err)
} else {
console.log('file downloaded')
}
});
});
Frontend App code:
HTML:
<button class="download-btn">download</button>
Script:
const handleDownload = async () => {
const res = await fetch("https://cors-anywhere.herokuapp.com/http://localhost:5000/download");
const blob = await res.blob();
download(blob, 'output.yml');
}
downloadBtn.addEventListener('click', handleDownload);
Folder Structure:
Update:
Server.js
const uploadFiles = async (req, res) => {
const file = await req.files[0];
console.log(file)
postmanCollection = file.path;
outputFile = `downloads/${file.filename}.yml`
convertCollection();
res.json({ message: "Successfully uploaded files" });
}
app.post("/upload_files", upload.array("files"), uploadFiles);
Anyone please help me with this.
You are already using res.send ,which sends the response headers back to client ,which ends the request response cycle ,and when you try to do res.download it throws error. Use instead
app.get('/download', (req, res) => {
const file = './downloads/output.yml';
res.download(file, 'openapi.yml', (err) => {
if (err) {
console.log(err)
} else {
console.log('file downloaded')
}
});
});
res.send('file downloaded')--->remove this line
You need to update your js code as well
const handleDownload = async () => {
const res = await fetch("https://cors-anywhere.herokuapp.com/download"); //http://localhost:5000--->this is not required
const blob = await res.blob();
download(blob, 'output.yml');
}
downloadBtn.addEventListener('click', handleDownload);
i use multer package with node and react and i send a file to node js backend, but always its undefined..
This is React
<div className="file-field input-field">
<div className="btn">
<span>File</span>
<input
type="file"
name="image"
id="image"
onChange={changedImageUpload}
/>
</div>
<div className="file-path-wrapper">
<input className="file-path validate" />
</div>
</div>
and that is onChange file handling method in there i just get first console.log but second and third is not printed
const changedImageUpload = (e) => {
const file = e.target.files[0];
const formData = new FormData();
formData.append("image", file);
console.log(formData, file);
try {
const config = {
Headers: {
"Content-Type": "multipart/form-data",
},
};
axios
.post("/uploads", formData, config)
.then((res) => {
console.log(res.data);
})
.catch((err) => {
console.log(err);
});
} catch (err) {
console.log(err);
}
};
and its Node codes and multer configure
import express from "express";
import multer from "multer";
const route = express.Router();
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, "images");
},
filename: (req, file, cb) => {
cb(
null,
new Date().toISOString().replace(/[\/\\:]/g, "_") + file.originalname
);
},
});
const multerFilter = (req, file, cb) => {
if (
file.mimetype === "image/png" ||
file.mimetype === "image/jpg" ||
file.mimetype === "image/jpeg"
) {
cb(null, true);
} else {
cb(null, false);
}
};
const upload = multer({ storage: storage, fileFilter: multerFilter });
route.post("/uploads", upload.single("image"), (req, res) => {
try {
// res.send(`/${req.file.path}`);
console.log(req.file);
} catch (err) {
console.log(err);
}
});
and import in app.js
import uploadRoutes from "./Routes/uploadRoutes.js";
app.use(uploadRoutes);
const __dirname = path.resolve();
app.use("/images", express.static(path.join(__dirname, "/images")));
so at printing formData i always get empty object, and if i print req.file i get an undefined in node js
Your filter function is wrong. You are comparing the mimeType to things like jpg which isn't a real MIME type, so your files are always filtered out.
You need to compare to image/png and image/jpeg instead.
I am using body-parser, multer and express in my mern stack app. I need to upload a file as well as some text from the form. I am sending the post request as follows:
function addPost(postdetail){
axios.post('http://localhost:4000/blog',postdetail,{ headers:{
"Content-Type": "multipart/form-data"
}}).then(res=>{
dispatch({
type:'ADD_DATA',
payload:res.data,
})
}).catch(error=>{
console.log(error)
})
}
When I add the header I get an empty object as the output of req.body. But when the multipart/form-data is not added I get other req.body but empty only for the file.
I have used the react hooks to set the state and appended the file using FormData. When the appended value is logged I get all the information of the uploaded file. So, I could know that the file is properly appended.
const Addpost=()=> {
const [title, settitle] = useState('')
const [des, setdes] = useState('')
const [file, setfile] = useState(null)
const {addPost}=useContext(Globalcontext)
const handleSubmit=(e)=>{
e.preventDefault()
const formData = new FormData()
formData.append('file', file[0])
console.log([...formData])
const addedValue={
title,
des,
formData
}
addPost(addedValue)
settitle('')
setdes('')
setfile('')
}
return (
<div>
<form onSubmit={handleSubmit}>
<input type="text" name="title" value={title} onChange={(e)=>settitle(e.target.value)}/>
<input type="text" name="des" value={des} onChange={(e)=>setdes(e.target.value)}/>
<input type="file" name="file" onChange={(e)=>{setfile(e.target.files)}} />
<button type='submit' value='submit'>Add Post</button>
</form>
</div>
)
}
export default Addpost
This is how I am using multer in the server side:
const express=require('express')
const multer=require('multer')
const path=require('path')
const storage = multer.diskStorage({
destination: function(req, file, cb) {
cb(null, __dirname+'/file/uploads/')
},
filename:function(req,file,cb){
cb(null,file.fieldname+path.extname(file.originalname))
}
})
const upload=multer({
storage:storage
})
exports.addPost=(upload.any(),(req,res)=>{
const post=new Blog()
post.title=req.body.title
post.des=req.body.des
post.file = req.file
post.save((err,doc)=>{
if(!err){
res.send(doc)
}
else{
console.log(err)
}
})
console.log(req.body)
})
I think the problem is only with the server-side where I am trying to upload the file using multer. After I have used the header in the axios post request I am not able to insert any information to the mongoose and I get {} for consoling req.body and other fields are undefined.
Since you are using multer.any(), an array of files will be stored in req.files (see https://www.npmjs.com/package/multer#any).
In your case you can simply use multer.single() as you're uploading a single image - the file will then be available under req.file, rest of the form data will be available under req.body:
exports.addPost=(upload.single('file'),(req,res)=> { ... });
I am trying to upload a single file, and store it in a folder in my app directory. On the frontend, I am successfully selecting a file and adding it to the state of the Uploader component. When I make the POST request to the Node route with Axios, I am getting undefined in the request body.
Here is the component:
import React, { Component } from 'react';
import axios from 'axios';
export default class SandboxGet extends Component {
constructor(props) {
super(props);
this.state = {
file: null
};
}
fileSelectHandler = event => {
const file = event.target.files[0];
this.setState({ file: file.name });
};
fileUploadHandler = () => {
const data = new FormData();
data.append('file', this.state.file);
console.log(data);
axios
.post('http://localhost:4000/upload/', this.state.file, {
// receive two parameter endpoint url ,form data
})
.then(res => {
// then print response status
console.log(res.statusText);
});
};
render() {
return (
<div className="uploaderContainer">
<div className="uploadInput">
<i className="fas fa-upload" />
<button className="uploadBtn">Select Files</button>
<input type="file" name="file" onChange={this.fileSelectHandler} />
<div className="fileName">{this.state.fileName}</div>
</div>
<button className="uploadFile" onClick={this.fileUploadHandler}>
Upload!
</button>
</div>
);
}
}
Here is the Node server:
const express = require('express');
const app = express();
const multer = require('multer');
const cors = require('cors');
app.use(cors());
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, '/storage');
},
filename: (req, file, cb) => {
cb(null, Date.now() + '-' + file.originalname);
}
});
const upload = multer({ storage: storage }).single('file');
app.post('/upload', (req, res) => {
console.log(req.file); // => returns nothing
console.log(req.body; // => returns nothing
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);
});
});
app.listen(4000, function() {
console.log('App running on port 3000');
});
I feel like I am getting close, but I am missing a big piece of the puzzle.
You are sending the this.state.file. You need to send the FormData.
In your case it is .post('http://localhost:4000/upload/', data)
Also, you need to send the multipart/form-data header.
const headers = {
'content-type': 'multipart/form-data'
}
Then,
axios.post('http://localhost:4000/upload/', data, {headers});
I tried to upload an image to a local folder with multer and React.I expect to success upload an image. However, as chrome debugger said Failed load resource: the server responded with a status of 500 (Internal Server Error) [http://localhost:3000/]
I guess my code send wrong format of data to a server side. I really appreciate if you give me a solution for this. I spend full of days to tackle this issue.
React
const TopPage = () => {
const [imageState, setImageState] = useState({
imageName: "",
imageData: ""
});
const onChange = e => {
setImageState({
imageName: "lovelove" + Date.now(),
imageData: e.target.files[0]
});
};
const onClick = async () => {
const { imageName, imageData } = imageState;
console.log(imageName);
console.log(imageData);
const fd = new FormData();
await fd.append("imageName", imageName);
await fd.append("imageData", imageData);
await axios.post("/", fd, (res, req) => console.log(res));
};
return (
<div enctype="multipart/form-data" action="/" method="post">
<input type="file" onChange={e => onChange(e)} />
<button onClick={onClick}>Submit</button>
<img src={imageState.defaultImage} />
</div>
);
};
Server
router.post("/", upload.single("myFile"), (req, res, next) => {
console.log(req.file);
if (!req.file) return res.send("Please upload a file");
const newImage = new Image({
imageName: req.body.imageName,
imageData: req.file.path
});
newImage
.save()
.then(result => {
console.log(result);
res.status(200).json({
access: true,
document: result
});
})
.catch(err => next(err));
});
Assuming you have already installed multer, If you see the following code
router.post("/", upload.single("myFile"), (req, res, next) => {
console.log(req.file);
The "myFile" has to be the name of the formField coressponding to the file that is being passed, which in your case is "imageData". Try replacing "myFile" with "imageData".
Also set headers for the axios post request being made from react. The form attributes may not have effect on the manual http requests
var header = {
'Content-Type': 'multipart/form-data'
}
await axios.post("/", fd,{ headers : header });
Try and let me know if it works.