Search code examples
node.jsexpressfile-uploadproxymultipartform-data

How to proxy multiple file upload using NodeJs?


Ok, so i need to proxy file array upload from my express node app, to remote PHP Api.

Ideally i would use something close to Nginx proxy since it has same modules with node.

If not,i would emulate form resend.

Can you help find the best way for doing this?


Solution

  • So, i did not found execaly how to proxy request itself, as it would do nginx, but at least i figured out how to redirect request with all it's data to different source.

    So, here we use express-fileupload to get our file data from req, and form-data to create a form and send data.

    import app from '@app';
    import { authMw as checkJwtAndAddToRequest } from '@middleware/Auth';
    import { Router } from 'express';
    
    import fileupload, { UploadedFile } from "express-fileupload";
    
    import FormData from 'form-data';
    
    //add this MW to add files to you'r req
    
    app.use(checkJwtAndAddToRequest)
    app.use(fileupload());
    
    app.post('/upload', (req, res) => {
        const uploadableFiles: UploadedFile[] | UploadedFile | undefined = req.files?.formFieldName;
    
        if(!uploadableFiles) {
            throw Error('Pls add files to upload them');
        }
    
        //Transorm single file to same form as an array of files
        const files: UploadedFile[] = Array.isArray(uploadableFiles) ? uploadableFiles : Array<UploadedFile>(uploadableFiles);
    
        //create form
        const form = new FormData();
    
        //add files
        files.forEach(
            file => form.append('files[]', file.data.toString(), file.name)
        )
    
        //Submit 
        form.submit({
            protocol: 'http:',
            host: process.env.API_URL,
            path: '/api-path-for/file/upload',
            method: 'POST',
            headers: {
                //Add auth token if needed
                authorization: `Bearer ${String(req.body.jwtToken)}`
            }
        }, (err, response) => {
            if(err) {
                //handle error 
                res.status(503).send('File server is currently unavailable');
            }
            //return remote response to original client
            response.pipe(res)
        });
    });