Upload PDF file to Express server
See if that solves your problem.
_handleUpload = (e) => {
const dataForm = new FormData();
dataForm.append('file', e.target.files[0]);
axios
.post('http://localhost:4000/test', dataForm)
.then(res => {
})
.catch(err => console.log(err));
}
render() {
return (
<div className="App">
<input
onChange={this._handleUpload}
type="file"
/>
</div>
)
}
server:
router.post('/test', upload.any(), (req, res) => {
console.log(req.files)
res.send({sucess: true})
})
No need to send the file type, the multer identifies the name and type for you.
ericgio
Updated on July 05, 2022Comments
-
ericgio almost 2 years
I've built a basic browser form allowing users to upload a PDF file. I then want to send that file to an Express backend. It seems like this should be a pretty basic action, but I'm unfamiliar with the end-to-end process so I'm not sure which piece is failing. I've searched through a number of SO questions/answers, but haven't found any that provide a complete solution, and I haven't been able to cobble together a solution either.
Update: It looks like the file is getting to the server, but the encoding is messed up. My guess is that
FileReader.readAsText
is the wrong method to use.FileReader.readAsBinaryString
got me a little closer, but still not quite right (and it's deprecated).FileReader.readAsArrayBuffer
seems like potentially the way to go, but I'm not sure how to correctly handle the buffer in Express.Client/Browser
The form is built in React and just uses an
onChange
handler on the input itself. When a file has been added, the handler reads the file, adds it to the form data and sends the post request to the server.// React form <input name="upload" onChange={this._handleUpload} type="file" /> _handleUpload = (e) => { const { files, name } = e.target; // Read the file const reader = new FileReader(); reader.onload = (e) => { const file = e.target.result; // Now that we have the file's contents, append to the form data. const formData = new FormData(); formData.append('file', file); formData.append('type', name); axios .post('/upload', formData) .then(res => { // Handle the response... }) .catch(err => console.log(err)); }; // Reading as text. Should this be something else? reader.readAsText(files[0]); }
Express App
The express app uses multer middleware to process the upload:
const app = express(); const upload = multer({}); app.use(express.json()); app.use(express.urlencoded({ extended: true })); app.use(cors()); app.post('/upload', upload.any(), handleUpload);
Middleware
Finally, I have my own middleware that gets the file from multer. I'm testing this piece by just writing the file I've received to disk. It has contents, but it's not a readable PDF file.
const handleUpload = (req, res, next) => { // The file shows up on req.body instead of req.file, per multer docs. const { file } = req.body; // File is written, but it's not a readable PDF. const tmp = fs.writeFileSync( path.join(__dirname, './test.pdf'), file, ); }
Is there some piece that I'm getting obviously wrong here? eg: Do PDFs need to be handled in a special way? Any tips for where to focus my debugging?
-
ericgio over 5 yearsYes, thank you! I mistakenly thought that I needed to read the file on the client before sending (using
FileReader
), but it turns out multer will handle all that on the other end. -
Vinoth over 3 yearsHi @justcase. Can you tell me how to download the saved files from node to reactjs