Sending image as binary via require("http") request to a remote server
Asked Answered
P

1

1

I'm trying to send an image to remote server from nodejs server. Here's the request format so far.

Note: Just like binary request in postman and choosing a file and sending)

function upload(options, body) {
    body = body || '';
    return new Promise(function(resolve, reject){
        const https = require('https');
        https.request(options, function(response) {
            var body = [];
            response.on('data', function(chunk) {
                body.push(chunk);
            });
            response.on('end', function(){
                resolve(JSON.parse(Buffer.concat(body).toString()))
            });
        }).on('error', function(error) {
            reject(error);
        }).end(body);
    });
}

Use:

var options = {
    hostname: "hostname",
    path: "/upload",
    port: 443,
    method: 'PUT',
    headers: {
        'Accept': 'application/json',
        'Content-Type': 'image/png'
    }
};

fs.readFile('./img/thumbnail.png', function(error, data) {
     options.body = data;
     upload(options).then(...
});

enter image description here

Edit 2

After several attempts, came across an efficient strategy to upload images via streams, here's how it looks like but still not success.

const https = require('https');
var request = https.request(options, function(response) {
    var buffers = [];
    response.on('data', function(chunk) {
        buffers.push(chunk);
    });
    response.on('end', function(){
        console.log(response.headers['content-type']);
        var body = JSON.parse(buffers.length ? Buffer.concat(buffers).toString() : '""');
        response.statusCode >= 200 && response.statusCode < 300 ? resolve(body) : reject(body);
    });
}).on('error', function(error) {
    reject(error);
});

const fs = require('fs');
var readStream = fs.ReadStream(body.path);
readStream.pipe(request);
readStream.on('close', function(){
    request.end();
});

Reference

Playa answered 24/6, 2016 at 23:23 Comment(15)
uploadImage(options, body) doesn't look right... where is body defined?Anole
sorry i fixed the typos, I'm confused about where to pass the image data to???Playa
Have you looked at other answers on this site, there are many examples of how to send data with Node, and most would probably recomend using the Request middleware.Quintuplicate
I've looked up so much, already spent hours, desperate in need of help, and can't use the Request, it has to be low level nodejs code.Playa
All I want is how can I send the binary data in node.js just like in postman's option. I've edited with a screenshot nowPlaya
Looks like you're already doing it, the data is in options.body and is sent to the remote server with that keyQuintuplicate
@Quintuplicate so for the sake of understanding and in context of my postman screenshot, binary -> options.body and for raw, x-www-form-urlencoded and form-data -> will go to body, please confirm or correct.Playa
still having issues, no on('data') or on('end') is getting called when I pass the image body in response.end(body) function, any advice guys?Playa
"But still not success" is not a description of a problem.Anole
I'm sorry, I'd say the remote server end is unable to receive my file, the code is working now though. so not sure if I'm sending the file property, Read Stream correctly reads my image, is Edit 2 correct in your opinion?Playa
@Playa I think that code is fine. I'm still not sure if you're having trouble or not.Anole
From the remote server's response headers content-type I see this value, application/octet-stream, maybe the remote server expects octet-stream, not sure how I can specify this while sending the image dataPlaya
I think I'm reaching the problem, there was an issue with the image, I selected another one now and guess what, readStream('close' is not getting called, it's a 3.1 MB imagePlaya
damn it's the timeout of mocha exiting from tests early, I've increased the timeout and works now, but nevertheless most importantly I learned how to send images via readStreamsPlaya
Did you find your answer?Bohr
A
0

I think you just want this:

fs.createReadStream('./img/thumbnail.png').pipe(https.request({
  hostname: 'hostname',
  path: '/upload',
  method: 'PUT',
  headers: {
    Accept: 'application/json',
    'Content-Type': 'image/png',
  }
}, function (response) { ... }));

The issue with your code is that you were putting the body into options.body, but per the documentation, it doesn't look like there is any such option.

Anole answered 25/6, 2016 at 0:13 Comment(7)
so all options from screenshot in my question, whether binary, raw, x-www-form-urlencoded and form-data, they all go into body, how to you specify Content-Type for each?Playa
I don't know what Postman means by those various things. In particular, I can't think of what "binary" versus "raw" might mean. x-www-form-urlencoded is presumably exactly that Content-Type (and formatting of the body), and form-data is probably multipart/form-data. You can easily look both of those up.Anole
Hi @smarx, guess what, I don't get any response in response.on('end', function(){ when I pass the image data directly into end() function, not even on response.on('data'), it's like everything freezes, is there something wrong with the way I'm reading image data and passing on?Playa
When you say you "don't get any response," do you mean that your handler is not called for those events?Anole
I've added another piece of code in the edit section, please review.Playa
You shouldn't be using readFile in this situation.Brade
@Brade smarx please review my Edit2 in my questionPlaya

© 2022 - 2024 — McMap. All rights reserved.