Michael Nelles
Michael Nelles

Reputation: 6032

NodeJS & express file upload with XMLHttpRequest - not working

I am uploading a file using this form and by the time xhr submits it the server does not recognize req.xhr === true, as such I can not process the file upload. What am I missing?

<form  encType="multipart/form-data" method="post">
    <Button onClick={(event)=>startUploadFile(event)} type="button">Upload</Button>
    <input type="file" name="file"  id="file" multiple="multiple" onChange={onChangeHandler} />
</form>

Client side

const [upFile, setUpFile] = useState('')

const onChangeHandler = event => {
    setUpFile(event.target.files[0]);
}

const startUploadFile = e => {
        setSpin('visible')
        setMsg(`Uploading Media ...`)
        e.preventDefault()

        const data = new FormData()
        data.append('file', upFile)

        var formData = new FormData();
        var xhr = new XMLHttpRequest();

        var onProgress = function(e) {
          if (e.lengthComputable) {
            var percentComplete = (e.loaded/e.total)*100;
            console.log('percentage = ' + percentComplete) 
          }
        };

        formData.append('files', upFile); // this is a state object set onChange
        xhr.open('post', '/upload', true);
        xhr.addEventListener('error', onError, false);
        xhr.addEventListener('progress', onProgress, false);
        xhr.send(formData);
        xhr.addEventListener('readystatechange', onReady, false);

    }

Server side

const express        = require('express'),
      app            = express.Router(),
      cors           = require('cors'),
      fs             = require('fs-extra');

app.use(cors())

app.post('/uploadFile', (req, res) => {

     if (req.xhr || req.headers.accept.indexOf('json') > -1) {
        // not accepted (req.xhr is false always) why?
     }
});

Upvotes: 0

Views: 1580

Answers (2)

Michael Nelles
Michael Nelles

Reputation: 6032

Thanks to @Nikas for the remarks - here is working solution if anyone needs it or something like it. For the client side:

const startUploadFile = e => {
        setSpin('visible')
        setMsg(`Uploading Media ...`)
        e.preventDefault()

        const data = new FormData()
        data.append('file', upFile)

        var formData = new FormData();
        var xhr = new XMLHttpRequest();

        var onProgress = function(e) {
            if (e.lengthComputable) {
              var percentComplete = (e.loaded/e.total)*100;
              console.log('% uploaded:' + percentComplete)
            }
          };

          var onReady = function(e) {
           console.log('ready')
          };

          var onError = function(err) {
            console.log('something went wrong with upload');
          };

        formData.append('files', upFile); // this is a state object set onChange
        xhr.open('post', '/media/uploadFile', true);
        xhr.addEventListener('error', onError, false);
        xhr.addEventListener('progress', onProgress, false);
        xhr.send(formData);
        xhr.addEventListener('readystatechange', onReady, false);

    }

server side:

const express       = require('express'),
      app            = express.Router(),
      cors           = require('cors'),
      fs             = require('fs-extra'),
      formidable     = require('formidable');

app.post('/uploadFile',  (req, res) => {

     const path = './client/public/upload/';

     var form = new formidable.IncomingForm();
     form.uploadDir = path;
     form.encoding = 'binary';

     form.parse(req, function(err, fields, files) {
          if (err) {
               console.log(err);
               res.send('upload failed')
          } else {
               var oldpath = files.files.path;
               var newpath = path + files.files.name;
               fs.rename(oldpath, newpath, function (err) {
                    if (err) throw err;
                    res.send('complete').end();
               });
          }
     });
})

Upvotes: 1

Nikas
Nikas

Reputation: 247

In expressjs you need to install multer or formidable package to upload file from client side application then you will receive your file in req.files object.

Upvotes: 1

Related Questions