Upload multiple files with XMLHttpRequest to Express.js 3.5 Server

13,123

Thx to @Pengtuzi I solved it:

I used the FormData API to upload the files. My mistake was that I thought the error would happen on the server.

Here's the code that solved it for me:

function uploadFiles(files) {
    var xhr = new XMLHttpRequest();
    var formData = new FormData();
    xhr.onload = successfullyUploaded;
    xhr.open("POST", "http://localhost:3000/upload", true);
    xhr.setRequestHeader('X-Requested-With','XMLHttpRequest');
    for(var file in files) {
        formData.append("uploads", files[file].data);
    }
    xhr.send(formData);
}
Share:
13,123
lehnerchristian
Author by

lehnerchristian

Updated on July 25, 2022

Comments

  • lehnerchristian
    lehnerchristian almost 2 years

    I'm trying to build a file uploader with the native FileAPI in JavaScript and I want to upload the files via XMLHttpRequest (without jQuery) to a Node.js server, which uses Express.js.

    The file reading part works fine and when I upload the file without the XMLHttpRequest it works perfectly (the files are in req.files in Express.js).

    The problem is the upload via AJAX: req.files is always empty.

    Heres some code:

    The form:

    <form action="http://localhost:3000/upload" method="POST" enctype="multipart/form-data" name="form">
      <input type="file" name="uploads" id="files" multiple="multiple">
      <input type="submit" name="submit" value="submit">
    </form>
    

    The upload part in the frontend (in files[0].data is a file - not an array or something):

    function uploadFiles(files) {
        var xhr = new XMLHttpRequest();
        xhr.submittedData = files; // Array of objects with files included. But it neither works with an array of files nor just one file
        xhr.onload = successfullyUploaded;
        xhr.open("POST", "http://localhost:3000/upload", true);
        xhr.setRequestHeader('X-Requested-With','XMLHttpRequest');
        xhr.send();
    }
    

    The backend where the problem occurs:

    exports.receiveUpload = function(req, res){
        console.log(req.files); // empty
        var files = req.files.uploads; // always empty with AJAX upload. with normal upload it's fine
        console.log(req.xhr); // true
        // ...
    }
    

    And here's some Express.js config (I already had the same error without AJAX - in the comments in the code you can see the lines and the Stack Overflow post that solved it for the upload without AJAX):

    // all environments
    app.set('port', process.env.PORT || 3000);
    app.set('views', path.join(__dirname, 'views'));
    app.set('view engine', 'ejs');
    app.use(express.favicon());
    app.use(express.logger('dev'));
    app.use(express.json());
    app.use(express.urlencoded());
    
    // this 3 lines have to be before app.use(app.router)
    // https://stackoverflow.com/questions/21877098/upload-file-using-express-failed-cannot-read-property-of-undefined
    app.use(express.multipart());
    app.use(express.bodyParser({ keepExtensions: true, uploadDir: path.join(__dirname, 'public', 'uploads') }));
    app.use(express.methodOverride());
    
    
    app.use(app.router);
    app.use(require('less-middleware')(path.join(__dirname, '/public')));
    app.use(express.static(path.join(__dirname, 'public')));
    

    Thanks in advance!

    Regards,

    C.