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.
Create the form object for submission The formData will contain the file object which can be easily appended. Then an AJAX request can be created by using XMLHttpRequest() method. This would be a POST request to /upload which is same as the one we mentioned while creating HTML form in Step 1.
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);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With