node.jsformsfile-uploadbusboy

What's the difference between the 'field' and the 'file' events in busboy?


Busboy is the middleware I'm using to upload a file. Using an html form inside Chrome, I can upload files (using the 'file' event) but when an android client tries to upload a file, it doesn't trigger the 'file' event, it triggers the 'field' event instead.

Here the code snippet I am using on the server side:

import express from 'express';
import busboy from 'connect-busboy';

const app = express();

const busUpload = (req, res)=> {
    req.busboy.on('file', function(fieldname, file, filename, encoding, mimetype) {
        saveTo = `${destination}/${filename}`;

        Log('uploading to', saveTo);
        file.pipe(fs.createWriteStream(saveTo));
        // file is saved successfully.
    });

    req.busboy.on('field', function(key, value, keyTruncated, valueTruncated) {
    //  I guess 'value' contains the file, but how do I save it? what is the name of file?
    });

    req.busboy.on('finish', function() {
        Log('upload completed');
        // res.writeHead(200, {'Connection': 'close'});
        res.json({sucess: true});
    });

    // req.pipe(req.busboy);

};

‍‍app.use('/uploads', busboy({immediate: true}), busUpload)

‍‍‍What's the difference? What should I tell the android developer to change in his request? Or how can I save the file inside the handler of the 'field' event?


Solution

  • According to the busboy documentation the file event is triggered for file uploads:

    • Emitted for each new file form field found. transferEncoding contains the 'Content-Transfer-Encoding' value for the file stream. mimeType contains the 'Content-Type' value for the file stream.

    Since you get a field event my guess would be that the input is not sent similarly as in an html file input element:

    <input type="file" name="filename" accept="media/type">
    

    I am not familiar with android API so not sure how files are sent, but since your field event is triggered it seems you should dive into the client side (Android) of the code and see what possibilities you have.

    Alternatively you can validate whether your field input contains a file like you already suggested in the code snippet in your question above:

    //  I guess 'value' contains the file, but how do I save it? what is the name of file?
    

    You can simply check what you get from your client by debugging/analyzing/logging your request object.


    If you don't have the possibility to work on the client side code yourself, you could also try building a small html upload page where you upload files to your server and see what behavior you get. Like that you will be able to check easily if your server is working as expected. In this small application could upload files in different ways:

    1. through a form as in the example here
    2. as binary content as in the example here

    And test whether your server is able to handle the file correctly in both cases.