Seph Reed
Seph Reed

Reputation: 10938

How can I recieve a blob with Vanilla Node.js?

I have vanilla code for getting the body of a request, but it creates a string. So far, this has worked fine for most things, but now I want to receive a blob.

First off, the code I have now:

http.createServer(function (request, response) {
  var body = '';

  request.on('data', function (data) {
    //this works great for UTF-8, but does not work for Blobs
    body += data;

    // Too much POST data, kill the connection!
    // 1e6 === 1 * Math.pow(10, 6) === 1 * 1000000 ~~~ 1MB
    if (body.length > 1e7) {
        console.log("POSTED data too large!")
        request.connection.destroy();
    }
  });

  request.on('end', function () {
    var pathname = "test.png";
    fs.writeFileSync(pathname, body, {flag: "w"});

    response.writeHead(200, {
      'Content-Type': 'text/plain',
      "Access-Control-Allow-Origin" : "*"
    });
    response.end("got it")
  });

}).listen(8888);

Client Side:

var imgNode; //assume is loaded <img>
var canvas = document.createElement("canvas");
canvas.width = imgNode.naturalWidth;
canvas.height = imgNode.naturalHeight;
var ctx = canvas.getContext("2d");
ctx.drawImage(imgNode, 0, 0);  

canvas.toBlob(function(blob) {
  Ajax.POST("localhost:8888", blob);  //functional Ajax POST
});

The issue here is that this code only works for strings. What is some Vanilla code that would work for Blobs?

Upvotes: 0

Views: 1772

Answers (1)

Jaromanda X
Jaromanda X

Reputation: 1

using Buffer instead of a string should work, like so

http.createServer(function (request, response) {
    var body = Buffer.from([]); // create a buffer

    request.on('data', function (data) {
        // add to buffer
        body = Buffer.concat([body,data]);
        // Too much POST data, kill the connection!
        // 1e6 === 1 * Math.pow(10, 6) === 1 * 1000000 ~~~ 1MB
        if (body.length > 1e7) {
            console.log("POSTED data too large!")
            request.connection.destroy();
        }
    });
    request.on('end', function () {
        var pathname = "test.png";
        fs.writeFileSync(pathname, body, {flag: "w"});

        response.writeHead(200, {
              'Content-Type': 'text/plain',
              'Access-Control-Allow-Origin' : '*',
              // note: I had to add these because of the OPTIONS request
              'Access-Control-Allow-Headers' : 'Content-Type',
              'Access-Control-Allow-Methods' : 'GET,PUT,POST,DELETE,OPTIONS'
        });
        response.end("got it")
    });

}).listen(8888);

When I tried testing your code, I was getting an OPTIONS preflight - the code above "handles" it, but it's hacky at best - as you don't seem to have an OPTIONS preflight (because you don't handle it in your code) I figure it's just something I've done wrong with your code

There's probably a far better way to add the data to the buffer - I haven't done stuff like this with node in a while

Upvotes: 2

Related Questions