Search code examples
expressbusboy

Busboy + Express: How to get the sended file and its specifications


I struggle on a very simple example for Express.js and Busboy. The code is as simple as possible. That makes it easier for me and others to understand whats going on. the form block:

            <form
              action="https:// ... this works ..."
              enctype="multipart/form-data"
              method="post"
            >
              <label class="up_styles">
                <input type="file" name="file" id="somethingTricky"/>
              </label>
              <br />
              <input class="sub" type="submit" value="Submit" />
            </form>

and the backend:

const functions = require("firebase-functions");

const Busboy = require('busboy');

const express = require("express");

const app = express();

app.post("/api/fileanalyse", (req, res) => {
 const busboy = new Busboy({
    headers: req.headers
});

busboy.on('error', function(err) {
    console.log(err);
});

busboy.on('file', function(fieldname, file, filename, encoding, mimetype) {
    console.log(fieldname);
    console.log(file);
    console.log(filename);
    console.log(encoding);
    console.log(mimetype);

    // see other question
    file.resume();

});

busboy.on('finish', function() {
    console.log('finish');
});

return req.pipe(busboy);
});

exports.App = functions.region("europe-west1").https.onRequest(app);

All the console.logs in the function(fieldname, file, filename, encoding, mimetype) dont work, console.log('finish') works. How do I get the file and the filedata, for example filename and filesize from the request?


Solution

  • Okay, it had to go on and found another solution without using Node.js, Express.js and busboy (or something like "express-busboy", "connect-busboy" ...). Using React.js (create-react-app) and Firebase/storage:

    Running solution: https://filemeta-4dcb1.firebaseapp.com/

    And the code:

    App.js(will be attached to the Div(root) by index.js):

    import React from 'react';
    import Upload from './component/upload';
    
    function App() {
      return (
        <div className="App">
            <h1>file metaservice</h1>
            <Upload />
        </div>
      );
    }
    
    export default App;
    

    upload.js(this component includes everything except of the Firebase init):

    import React, { Component } from "react";
    import Firebase from "./firebase";
    
    class Upload extends Component {
      constructor(props) {
        super(props);
        this.state = {
          file: "",
        };
        this.setFileState = this.setFileState.bind(this);
        this.fileUpload = this.fileUpload.bind(this);
      }
      setFileState = (e) => {
        this.setState({ [e.target.name]: e.target.files[0] });
      };
      fileUpload = (e) => {
        e.preventDefault();
        // if no file is selected
        if (!this.state.file) {
          console.log("please select a file");
        } else {
          // send file to the database
          const storageRef = Firebase.db.ref('fileupload/' + this.state.file.name);
          storageRef.put(this.state.file);
          storageRef.getMetadata().then(res => {
            document.getElementById('fileDiv').innerText = 'fileName: ' + res.name + ', fileSize: ' + res.size + "b" 
          })
        }
      };
      render() {
        return (
          <div id="fileDiv">
            <form>
              <label>
                <input type="file" name="file" onChange={this.setFileState} />
              </label>
              <br />
              <input type="submit" value="Submit" onClick={this.fileUpload} />
            </form>
          </div>
        );
      }
    }
    
    export default Upload;
    

    and the firebase.js(to init Firebase):

    import app from "firebase/app";
    import "firebase/storage";
    
    const firebaseConfig = {
        my firebaseConfig - data ...
      };
    
    class Firebase {
      constructor() {
        app.initializeApp(firebaseConfig);
        this.db = app.storage();
      };
    };
    
    export default new Firebase();
    

    package.json(dependencies):

    {
      "dependencies": {
        "@testing-library/jest-dom": "^4.2.4",
        "@testing-library/react": "^9.5.0",
        "@testing-library/user-event": "^7.2.1",
        "react": "^16.13.1",
        "react-dom": "^16.13.1",
        "react-scripts": "3.4.1",
        "firebase": "*"
      }
    

    Cheers!