Search code examples
node.jsecmascript-6multipartform-dataform-data

Forwarding FormData() request from NodeJS to another service


I am trying to forward my request from my NodeJS Proxy server to another server. The request I am trying to forward contains FormData()

I created FormData as per MDN docs

const payload = new FormData();
payload.append('addresses', file);  // <---- UPLOADED FILE
payload.append('reason', 'reason');
payload.append('type', 'type');

This is how I am essentially sending the request to my NodeJS server

fetch("localhost:3000/v1/addresses", {
  method: 'PUT',
  body: payload
});

NodeJS Server at localhost:3000

const multer = require('multer');
const upload = multer();

app.put('/v1/addresses', upload.single('addresses'), (req, res) => {
  let options = {
    host: 'localhost',
    method: 'PUT',
    port: 8000,
    path: req.originalUrl,
    headers: req.headers,
    formData: {
      reason: req.body.reason,
      type: req.body.type,
    }
  };

  console.log("reason", req.body.reason) // "reason"
  console.log("type", req.body.type)     // "type"
  console.log("addresses", req.file)     // FILE OBJECT

  const request = http.request(options, response => {
    res.writeHead(response.statusCode, response.headers);
    response.pipe(res);
  });

  request.end();
})

The code above, I'm not sure how to send over the actual file to the other service. Also, I am NOT seeing the reason and and type that I've passed over to the service.

What's also strange is that I see this in the incoming request in my NON- PROXY server

PUT /v1/addresses HTTP/1.1
Host: localhost:3000
Connection: keep-alive
Content-Length: 932
Sec-Ch-Ua: "Google Chrome";v="89", "Chromium";v="89", ";Not A Brand";v="99"
Sec-Ch-Ua-Mobile: ?0
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 11_2_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryt2p0AWOqJCnz95hg
Accept: */*
Origin: http://localhost:3000
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: http://localhost:3000/blocklist
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9

[object Object]

Solution

  • So after lots of searching and experimenting, this post actually provided me with the answer

    Here is the code from the post.

    const express = require("express");
    const app = express();
    const bodyParser = require('body-parser');
    var multer  = require('multer')();
    const FormData = require('form-data');
    const axios = require('axios');
    const fs = require('fs');
    
    app.use(bodyParser.json());
    
    app.post('/fileUpload' , multer.single('fileFieldName'), (req , res) => {
        const fileRecievedFromClient = req.file; //File Object sent in 'fileFieldName' field in multipart/form-data
        console.log(req.file)
    
        let form = new FormData();
        form.append('fileFieldName', fileRecievedFromClient.buffer, fileRecievedFromClient.originalname);
    
        axios.post('http://server2url/fileUploadToServer2', form, {
                headers: {
                    'Content-Type': `multipart/form-data; boundary=${form._boundary}`
                }
            }).then((responseFromServer2) => {
                res.send("SUCCESS")
            }).catch((err) => {
                res.send("ERROR")
            })
    })
    
    const server = app.listen(3000, function () {
        console.log('Server listening on port 3000');
    });