0

I have been going through this the whole afternoon, please help me debug.

Client Side:

fetch('/admin/edit/tags', {
    method: 'post',
    credentials: 'same-origin',
    headers: {
        'content-type': 'application/json',
        'accept': 'application/json'
    },
    body: form.getFormData('json')
})...

console.log(form.getFormData('json')); returns {"id":"11","tag":"tag12","submit":"Update"}

Server Side (Node.js):

Code for request handling:

function (req, res) {
    var bufferBody = [];
    req.on('error', err => {
      return res.status(400).send('request error.');
    }).on('data', chunk => {
      bufferBody.push(chunk);
    }).on('end', () => {
      res.on('error', err => {
        return res.status(400).send('response error.');
      });
      req.bufferBody = bufferBody;
      req.stringBody = Buffer.concat(bufferBody).toString();
      //req.json = JSON.parse(req.stringBody);
      req.body = qs.parse(req.stringBody);
    })
}

The Route:

{
    method: 'POST',
    path: '/admin/edit/tags',
    handle: PC(function*(req, res) {
        var data = req.body;
        console.log(data);
        console.log(req.stringBody);
    })
}

This is the buffer string: theBuffer.toString() %7B%22id%22%3A%2211%22%2C%22tag%22%3A%22tag12%22%2C%22submit%22%3A%22Update%22%7D=

This is the query string: qs.parse(theBufferString) { '{"id":"11","tag":"tag12","submit":"Update"}': '' }

I have checked every where, headers are correct. What could be the cause that could turn jsonString to queryString?

I know that I can turn jsObject to queryString, but I really really want to use jsonString.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
alexcres
  • 53
  • 2
  • 12
  • No, that post is specific to jsfiddle. I have seen that post hours ago. – alexcres Jul 19 '17 at 12:16
  • @AlexBlex That post is specific to jsfiddle, and suggest using `query string` instead of `json string`. But isn't `fetch` is supposed can work with `json string`? – alexcres Jul 19 '17 at 12:25
  • It has a very valid example of how to POST using fetch and formdata. – Alex Blex Jul 19 '17 at 12:34
  • Can you post code for node.js to handle the request? – Łukasz Szewczak Jul 19 '17 at 12:35
  • @ŁukaszSzewczak I have added the code for the request, please take a look. – alexcres Jul 19 '17 at 12:44
  • @AlexBlex That post first answer uses `multipart form data`, second answer uses `query string`, third answer is specific to jsfiddle can only process `form-urlencoded`. But I just want to use simple `json string`. – alexcres Jul 19 '17 at 12:49
  • @ŁukaszSzewczak There isn't anything special, server side just read the buffer, doesn't change anything. So the problem must be client side with `fetch`. Make sense? – alexcres Jul 19 '17 at 13:02
  • @YuchengXu There is no problem with your fetch code. Code is corrrect. Why you dot'n use some packeges like `body-parser` for `express.js` to get body of request? – Łukasz Szewczak Jul 19 '17 at 13:16
  • @ŁukaszSzewczak Because It's fun to build most of things on my own. And I have learned a lot along the way. – alexcres Jul 19 '17 at 13:27

1 Answers1

0

I figured out the problem. It's on server side.

I write my own request client, and in the client I turned any req.body to query string. Because before I was just following the example: https://nodejs.org/api/http.html (scroll to the end) in Node.js document. So I added req.headers['content-type'] check, if josn, use JSON.stringify, else qs.stringify.

if (options.body) {//solve socket hangup problem
    if (isJSON()) {
    // TODO add more content-type, not just json
    //e.g for forms: application/x-www-form-urlencoded
        options.body = JSON.stringify(options.body);
    }   else {
        options.body = qs.stringify(options.body);
    }
    options.headers['content-length'] = Buffer.byteLength(options.body);
} 
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
alexcres
  • 53
  • 2
  • 12