2

I am working on a react component where I want to upload a excel file to a server. Here is what I am trying. But it gives me an empty object when I console request body

<input type="file" id="avatar" name="avatar" onChange={this.fileHandler.bind(this)} style={{"padding":"10px"}}/> 

Here is file handler method which will execute when input file changed:

fileHandler = (event) => { event.preventDefault(); let fileObj = event.target.files[0]; console.log(fileObj); //console.log(JSON.stringify(fileObj)); var data = new FormData() data.append('file', fileObj) fetch("/upload", { method: 'POST', body: data }).then(function(response) { if (response.status >= 400) { throw new Error("Bad response from server"); } return response.text(); }).then(function(data) { console.log(data) }).catch(function(err) { console.log(err) }); } 

Here is the server code to upload a file.

app.post('/upload', function(req, res) { console.log(req.body); // Output : {} or undefined /*try { if(!req.files) { res.send({ status: false, message: 'No file uploaded' }); } else { let avatar = req.files.avatar; //Use the mv() method to place the file in upload directory (i.e. "uploads") avatar.mv('./uploads/' + avatar.name); //send response res.send({ status: true, message: 'File is uploaded', data: { name: avatar.name, mimetype: avatar.mimetype, size: avatar.size } }); } } catch (err) { res.status(500).send(err); }*/ }) 

If I try below using form action it is giving me correct output in req.files but I don't want to redirect.

<form id="myForm" method="post" encType="multipart/form-data" action="/upload"> <input type="hidden" name="msgtype" value="2"/> <input type="file" id="avatar" name="avatar" onChange={this.fileHandler.bind(this)} style={{"padding":"10px"}}/> <input type="submit" value="Upload" /> </form> 

Also I don't want to use axios as I am using the same fetch request for all other execution. Any help is appreciated.

9
  • have you googled "Upload file using fetch()"? Commented Apr 9, 2020 at 12:13
  • I got this 1st result by doing so and it has everything well explained in it flaviocopes.com/how-to-upload-files-fetch Commented Apr 9, 2020 at 12:15
  • @ZohaibIjaz I am working on this since long time and I tried everything as per suggestion but no luck. Commented Apr 9, 2020 at 12:21
  • Have you tried the solution I mention in previous comment? Commented Apr 9, 2020 at 12:26
  • @ZohaibIjaz yes, the same I did as you can compare the code with the link you have posted but output is undefined Commented Apr 9, 2020 at 12:27

2 Answers 2

2

Finally, I am able to deal with the correct request parameters using fetch. Here is the solution which I tried and working as expected:

<form id="myForm" method="post" encType="multipart/form-data" action="/upload" onSubmit={this.fileSubmit.bind(this)}> <input type="hidden" name="msgtype" value="2"/> <input type="file" id="avatar" name="avatar" onChange={this.fileHandler.bind(this)} style={{"padding":"10px"}}/> <input type="submit" value="Upload" /> </form> 

and here is the submit handler:

fileSubmit = (event) => { event.preventDefault(); fetch(event.target.action, { method: 'POST', body: new FormData(event.target) // event.target is the form }).then((resp) => { return resp.json(); //console.log(resp.json()); }).then((body) => { // TODO handle body console.log(body); if(body.status) { alert(body.message); } else { alert("Please Select a file to upload"); } }).catch((error) => { // TODO handle error // }); 

and on server side I am able to get req.files as well as the req.body.

app.post('/upload', function(req, res) { console.log(req.body); // which gives me form data console.log(req.files); // which gives me file object }); 
Sign up to request clarification or add additional context in comments.

Comments

0

I really don't know what I am doing wrong with fetch but I achieved file upload by redirecting form's action to an invisible . Here I am able to prevent form redirect.

<iframe name="dummyframe" id="dummyframe" style={{"display": "none"}}></iframe> <form id="myForm" method="post" encType="multipart/form-data" action="/upload" target="dummyframe"> <input type="hidden" name="msgtype" value="2"/> <input type="file" id="avatar" name="avatar" onChange={this.fileHandler.bind(this)} style={{"padding":"10px"}}/> <input type="submit" value="Upload" /> </form> 

So without fetch I am getting the file object at my server side like below:

app.post('/upload', function(req, res) { console.log(req.files); // Output : {avatar:{name:"", data: "", size:"", mimetype:""}} }) 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.