Home > database >  Sending file throught multipart/form-data from ReactJS to Express.js
Sending file throught multipart/form-data from ReactJS to Express.js

Time:07-27

I am struggling to find solution to send image from my reactjs application to my nodejs/express one.

In nodejs I have this setup:

var express = require('express')
var router = express.Router()
var multer = require('multer')
var upload = multer({dest: 'uploads/clanak/', limits: 10 * 1024 * 1024})

router.post('/insert', upload.single('thumbnail'), function(req, res) {
    console.log(req.body)
    console.log(req.thumbnail)
    console.log(req.body.thumbnail)
    return res.status(200).end()
})

module.exports = router

and here is app.js

var express = require('express')
var bodyParser = require('body-parser')
var cors = require('cors')
var cookieParser = require('cookie-parser')

var app = express()

app.use(cors({ origin: 'http://localhost:3001', allowedHeaders: '*'}))

app.use(cookieParser())
app.use(bodyParser.json({limit: "10mb", extended: true}))
app.use(bodyParser.urlencoded({ extended: true }))

var apiKorisnik = require('./routers/korisnik')
app.use('/korisnik', apiKorisnik)

var apiKorisnikTip = require('./routers/korisnikTip')
app.use('/korisnik/tip', apiKorisnikTip)

var apiClanak = require('./routers/clanak')
app.use('/clanak', apiClanak)

app.listen(3000)
console.log("Started @ http://localhost:3000/")

When I send data throught postman, it does accept it and it works, but when I try to do the same from my reactjs then request comes empty.

Here is code from my reactjs

import './Home.css'

function Home() {
    return(
        <div className='home-page-wrapper'>
            <input type='file' onChange={setFile.bind(this)}/>
        </div>
    )

    function setFile(event) {
        var formData = new FormData()
        console.log(event.target.files[0]) /* This prints file in console*/
        formData.append('someData', "hello") /* tried to see if I have problem with file only but this one is also not sent to server */
        formData.append('thumbnail', event.target.files[0])
        window.fetchAPI("/clanak/insert", "POST", "multipart/form-data;", formData, function(data) {
            console.log(data) /* It returns without error */
        })
    }
}
export default Home

and here is window.fetchAPI function:

window.fetchAPI = function(endpoint, method, contentType, body, callback) {
  const cookies = new Cookies();
  var auth = cookies.get("ARToken");
  fetch("http://localhost:3000"   endpoint, {
    method: method,
    headers: {
        'Content-Type': contentType,
        'Authorization': 'bearer '   auth 
    },
    body: body
  })
  .then((response) => {
    callback(response);
  })
}

I do not get any error but also no data when sending request from reactjs app.

I also tried writing content-type like: multipart/form-data: boundary=add-random-characters but it did not work.

EDIT:

Here is request pulled out from browser (here i send only string without file)

Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: sr-RS,sr;q=0.9,en-US;q=0.8,en;q=0.7
Authorization: bearer undefined
Connection: keep-alive
Content-Length: 144
Content-Type: multipart/form-data;
Host: localhost:3000
Origin: http://localhost:3001
Referer: http://localhost:3001/
sec-ch-ua: ".Not/A)Brand";v="99", "Google Chrome";v="103", "Chromium";v="103"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-site
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36

As I can tell, it has content-length so data is passed. It also has multipart/form-data header.

CodePudding user response:

I found solution. When you are posting multipart/form-data you do not set content-type. You leave it blank and browser does it for you.

Got the answer from this answer

CodePudding user response:

Can you please try this?

const multer = require('multer')
const { v1: uuidV1 } = require("uuid")

const MIME_TYPE_MAP = {
    "image/png": "png",
    "image/jpeg": "jpeg",
    "image/jpg": "jpg"
}

const uplaod = multer({
    limits: 500000,
    storage: multer.diskStorage({
        destination: (req, file, cb) => {
            cb(null, "uploads/clanak/")
        },
        filename: (req, file, cb) => {
            const ext = MIME_TYPE_MAP[file.mimetype]
            cb(null, uuidV1()   "."   ext)
        }
    }),
    fileFilter: (req, file, cb) => {
        const isValid = !!MIME_TYPE_MAP[file.mimetype]
        let error = isValid ? null : new Error("Invalid File Type!")
        cb(error, isValid)
    }
})

console.log(req.file);

console.log(req.files);

  • Related