Large strings are not completely passing from client to server by POST method in node

I’m working on a blog website using Node + JS at https://rv-blog.glitch.me

In this project, we prompt the user to chat using text + image. The text part is working fine, the problem is with the image part. Firstly, there is a file input which process images (line no: 160-173, script.js), then we prepare and send a request string to server (line no: 117-132, script.js). There we had a console log, which logs the length of request string (line no: 128, script.js). At this point, client-side task is over.

Now, we have a Node server which captures the request string (line no: 27,28,29, in server.js). I’ve a problem here that, client and server logs different length of the same request string. I know client-side can’t be wrong as it is generating the string. My doubt is that the server is not completely capturing the string, as:

  • it outputs a different length from the client
  • it outputs different length every time, instead of a unique one

However, when I was trying this on localhost, I was fortunate once and the image got uploaded as shown below, so I guess my server-side code is working fine atleast.


EDIT

It works for small images as seen in screenshot:

I understood why this is happening. It’s bcoz node receives large request datas in chunks, and so I got partial JSON data, and Node threw error.

For testing purposes, one can check the following code on localhost:

  • index.js
let http = require('http'),
    fs = require('fs');

http.createServer((req, resp) => {
  if(req.method === 'GET' && req.url === '/') {
    fs.readFile('./index.html', (err, res) => {
      resp.writeHead('200', { 'Content-Type': 'text/html' });
      resp.end(res, 'utf8');
    });
  } else if(req.method === 'POST') req.on( 'data', chunk => console.log('Length', chunk.length) );
}).listen(8080);
  • index.html
<input type="file" accept="image/*" onchange="f(this);">
<script>
function f(el) {
	var fr = new FileReader();
	fr.onload = function() {
		console.log('Length', fr.result.length);
		var xhr = new XMLHttpRequest();
		xhr.open('POST', '/', true);
		xhr.send(fr.result);
	};
	fr.readAsDataURL(el.files[0]);
};
</script>

A handy solution

Write something like,

let chunk = '';
req.on('data', _chunk => chunk += _chunk).on('end', () => {
  // do something with chunk
});
1 Like