Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sending a buffer in multipart/form-data POST request Node | Express | request

I have a buffer that I have taken from users uploaded image, that I then want to send on to another API in a multipart/form-data POST request.

I'm having issues however with the request object. I want to send a stream or buffer rather than accessing local server file system / creating temp files. I'm fairly new to the concept of streams.

I get the correct response from API sending
image_file: fs.createReadStream('image.png')

But when I try:
image_file: data // buffer

I get an error from the API saying I'm missing the image_file parameter.

Please help!

Docs for the API I'm using (Face++)
I'm using request to make the post request.

Here is my code in question:

app.post('/', (req, res) => {

    const url = 'https://api-us.faceplusplus.com/facepp/v3/detect';

    let data = [];

    req.on('data', (chunk) => {
        data.push(chunk)
    })

    req.on('end', (req, res) => {

        data = Buffer.concat(data);

        const formData = {
            api_key: process.env.FACEPP_API_KEY,
            api_secret: process.env.FACEPP_API_SECRET,
            // image_file: fs.createReadStream('image.png') // works
            image_file: data // doesnt work
        }

        const options = {
            uri: url,
            method: 'POST',
            formData
        }

        request(options, (err, response, body) => {
            if (err) console.log(err)
            console.log(body)
        })
    })
})
like image 302
twocents Avatar asked Mar 11 '18 07:03

twocents


1 Answers

After a little playing about, I have the following code, it's working nicely for me. I used the Multer middleware (https://github.com/expressjs/multer) for the original multipart upload. As a matter of interest, request doesn't seem to play nice uploading files unless you specify a filename option.

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

app.post('/', upload.any(), (req, res) => {

    const url = 'https://api-us.faceplusplus.com/facepp/v3/detect';

    console.log('Image upload complete, creating request to: ' + url);

    var formData = {
        api_key: process.env.FACEPP_API_KEY,
        api_secret: process.env.FACEPP_API_SECRET,
        image_file: {
            value: req.files[0].buffer, // Upload the first file in the multi-part post
            options: {
               filename: 'image_file'
            }
      }
    };

    const options = {
        uri: url,
        formData: formData,
        method: 'POST'
    }

    request(options, (err, response, body) => {
        console.log('Request complete');
        if (err) console.log('Request err: ', err);
        console.log(body)
    })        
})

I'm getting a response that looks like this:

{
    "image_id": "GuF0MUPoaTcL/rbbcg+2kA==",
    "request_id": "1520789753,d913cce4-118e-4893-a1ee-d1ace2b6a65b",
    "time_used": 142,
    "faces": [{
        "face_rectangle": {
            "width": 183,
            "top": 125,
            "left": 220,
            "height": 183
        },
        "face_token": "8b8e327edfc10730f344b1465934a478"
    }]
}

I tested the image upload to my local server using curl like so:

curl -v -i -F "data=@smiling_woman.jpg" -H "Content-Type: multipart/form-data" -X POST http://localhost:3000/
like image 80
Terry Lennox Avatar answered Sep 18 '22 10:09

Terry Lennox