0

I am attempting to send image data to a server API, though, the documentation included with the API only contains an example for JQuery, which I don't want to use with my nodejs project. Also, the JQuery example contains things that don't exist in Node, such as Blobs.

The example provided by the API is:

var sourceImage = new Image();
sourceImage.src = image; // add image data to object

sourceImage.onload = function() {
  // Create a canvas with the desired dimensions
  var canvas = document.createElement("canvas");
  var dim = 256; // the image size
  canvas.width = dim;
  canvas.height = dim;

  // Scale and draw the source image to the canvas
  canvas.getContext("2d").drawImage(sourceImage, 0, 0, dim, dim);

  var formDataWithCanvasImage  = createFormData(canvas);

  // Make ajax call here
}


function createFormData(canvas) {
  var b64Img = canvas.toDataURL();
  var binImg = dataURItoBlob(b64Img);
  var fileName = new Date().getTime();// Name the file with the current timestamp and no extension
  var fd = new FormData();
  fd.append("imageClass", "preview"); 
  fd.append("X-Requested-With", "Iframe");
  fd.append("X-HTTP-Accept", "application/json, text/javascript, */*; q=0.01");
  fd.append("file", binImg,fileName);
  return fd;
}

$.ajax({
  url: imageURL,
  data: formDataWithCanvasImage,
  processData: false,
  contentType: false,
  type: 'POST',
  error: function() {alert("error uploading image");},
  success: function(data){
    console.log(data);
  }
});

However, this wouldn't work with nodejs, because there is no canvas in nodejs, and no such thing as a blob. So, what I've done is read an image from the local disc and convert that buffer into an ArrayBuffer then encode it in analog-nico's request-promise like so:

let opts = {
        uri: 'https://*****.com/api/images',
        contentType: false,
        processData: false,
        type: 'POST',
        formData: {
            "imageClass": "application",
            "X-Requested-With": "Iframe",
            "X-HTTP-Accept": "application/json, text/javascript, */*; q=0.01"
            "file": arraybuffer

        },
    }

request.post(opts).then(data => {....});

but the code throws TypeError: source.on is not a function. Has anyone encountered this problem before? How did you resolve it?

  • Blob are part of JavaScript.... http://www.javascripture.com/Blob – Hackerman Aug 12 '16 at 14:11
  • Not part of nodejs. https://stackoverflow.com/questions/14653349/node-js-can%C2%B4t-create-blobs – orlando marinella Aug 12 '16 at 14:22
  • I think that you are missing the point...you can port Jquery to JavaScript and use plain JS...build the request on the client and send it to the server is a trivial task in almost every web-related programming language :) – Hackerman Aug 12 '16 at 14:56
  • Building a request in nodejs is -very- easy. Sending the image file is proving not to be, though. I also want to avoid using jquery on the whole: It and nodejs separate like oil and water. – orlando marinella Aug 12 '16 at 15:07
  • Like I said before....Jquery is a library written in JavaScript....so, everything you do on Jquery, can be done in plain JS...Node is basically JavaScript on the client and on the server...maybe you see that the syntax is different, but under the hood is all javascript :) – Hackerman Aug 12 '16 at 15:15
  • And that's what I've been trying to replicate, except for the fact it's going bork and not working properly. I pull the image up through a fs.readFile function (nodejs native), convert the resulting buffer into an arrayBuffer, then insert it into the 'opts' object which then is inserted into the linked request module. It's not the request itself I'm having issues with; This application uses requests in other capacities. It's the encoding and sending of the image because there's no such thing as a blob. – orlando marinella Aug 12 '16 at 15:22
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/120819/discussion-between-orlando-marinella-and-hackerman). – orlando marinella Aug 12 '16 at 15:33
  • For example you can use something like this: https://jsfiddle.net/robertrozas/orhnc1gs/ – Hackerman Aug 12 '16 at 16:02
  • That's essentially the request module broken down into pieces. The issue is, FormData doesn't -technically- exist in nodejs, either. – orlando marinella Aug 12 '16 at 16:07
  • There we go again xD....if you analize the request sent to the server, you are going to realize that is just a simple multipart request...there is no formdata object in the request...so your server can handle that...you can handle it on your server with the multer package for example. – Hackerman Aug 12 '16 at 16:11
  • It's not my server. I can't really modify how the server works, so I'm trying to figure out what I can do based off of the provided example. – orlando marinella Aug 12 '16 at 16:21
  • On your your node backend you should be able to save the file using something like: `fs.readFile` reading the request filepath – Hackerman Aug 12 '16 at 16:32
  • I'm using this backend to communicate with a different backend. `fs.readFile` captures the buffer of the image, and that's what I'm trying to send. – orlando marinella Aug 12 '16 at 16:32
  • Maybe you can, you know, use the divide and conquer focus....divide your problem on small pieces and start solving them, one by one....also, you can start another question seeking advices on how to plan your development based on your specific requirement and showing what you have now vs what you want to accomplish, also pointing out that you want to consume or communicate with an external backend and that you have no control over that backend... – Hackerman Aug 12 '16 at 16:39
  • This is already a small piece of the problem. The question here is "How can I get this image file to this location, given these circumstances. Here is some examples that were provided, that won't work on my machine." The rest of the application is currently working A-Okay: It's this part that's not working. – orlando marinella Aug 12 '16 at 16:41

1 Answers1

-1

You could try loading the image from disk as a ReadStream and piping that using the request module to the API.

Rough Example: fs.createReadStream(filename).pipe(request.put('http://example.com/api/images'))

The module is available via npm install request.

kurt343
  • 145
  • 1
  • 13