fetch POST fails on post json body with sails.js
Asked Answered
P

1

1

I'm getting the following error within the body-parser when I try to POST a simple json body in to my controller using fetch

    1] error: Unable to parse HTTP body- error occurred ::
 'SyntaxError: `Unexpected token -\n    at parse (/project/node_modules/body-parser/lib/types/json.js:83:15)\n    
    at /project/node_modules/body-parser/lib/read.js:116:18\n    at invokeCallback (/project/node_modules/raw-body/index.js:262:16)\n    at done (/project/node_modules/raw-body/index.js:251:7)\n    at IncomingMessage.onEnd (/project/node_modules/raw-body/index.js:307:7)\n    at emitNone (events.js:86:13)\n    at IncomingMessage.emit (events.js:185:7)\n    at endReadableNT (_stream_readable.js:973:12)\n    at _combinedTickCallback (internal/process/next_tick.js:74:11)\n    at process._tickDomainCallback (internal/process/next_tick.js:122:9)`'

I debugged the body-parser and the reason I found why fails on parse is because receive a string wrapped

------WebKitFormBoundary.

if (strict) {
    console.log("body--->", body);
  var first = firstchar(body)

  if (first !== '{' && first !== '[') {
    debug('strict violation')
    throw new SyntaxError('Unexpected token ' + first)
  }
}

body---> ------WebKitFormBoundaryE7nkf6ervMA9VlRo
[1] Content-Disposition: form-data; name="json"
[1] 
[1] {"hola":1}
[1] ------WebKitFormBoundaryE7nkf6ervMA9VlRo--

and I have no idea how to get of rid of that.

The request is fairly simple

var data = new FormData();
data.append( "json", JSON.stringify( {"hi": 1} ) );
const options = {
    credentials: 'include',
    body : body
};

var request = new Request('/api/settings', {
    method: 'POST',
    redirect: 'follow',
    headers: new Headers({
        'Content-Type': 'application/json'
    })
});

fetch(request, options).then(function(response) {
  ...
})

The custom controller is a bit irrelevant because my request never reach the express route wrapped by sails.

'POST /settings': {
    controller: 'SettingsController',
    action: 'save'
},

The request details.

Request URL:https://localhost:3005/settings
Request Method:POST
Status Code:400 Bad Request
Remote Address:[::1]:3005
Response Headers


HTTP/1.1 400 Bad Request
Content-Type: text/html; charset=utf-8
Content-Length: 879
ETag: W/"36f-yM7k6L+nVm6aoKcn9HH5aQ"
Date: Wed, 01 Feb 2017 16:00:15 GMT
Connection: keep-alive
Request Headers
view parsed

POST /settings HTTP/1.1
Host: localhost:3005
Connection: keep-alive
Content-Length: 145
Pragma: no-cache
Cache-Control: no-cache
accept: application/json, application/xml, text/plain, text/html, *.*
Origin: https://localhost:3005
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.95 Safari/537.36
content-type: application/json
Referer: https://localhost:3005/
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.8
Cookie: sails.sid=s%3AjzHwjq3AK12uG5AMQTQRZLoQ-7WaWeWN.MP3Joor2lBWEMbkuDqaXj7Y7%2Fdj1v8PJ9kGTJtTGkLY
Request Payload
------WebKitFormBoundary8A2lXn22y5Rxm12f
Content-Disposition: form-data; name="json"

{"hi":1}
------WebKitFormBoundary8A2lXn22y5Rxm12f--

I tried with several samples but it seems I'm overlooking something here.

Pneumogastric answered 1/2, 2017 at 16:33 Comment(3)
Did you try hitting the api end point from postman or any other request sending utility?Mcbrayer
Try exactly what Sapna wrote above. Access API with Postman and check. It can be something wrong with your request. How you making your request?Malignant
With Postman works fine using the same configuration, with the content-type: application/json included I'm able to reach my controller. Today I found the solution here https://mcmap.net/q/49469/-fetch-post-json-data, with fetch I must use 'Content-Type': 'x-www-form-urlencoded' instead the other one (I'm using Chrome 56) to make it work. So I wonder why not with content-type: application/jsonPneumogastric
T
3

What is the reason to create FormData object?

It can be simplify as

fetch(new Request('/api/settings', {
    method: 'POST',
    redirect: 'follow',
    headers: new Headers({
      'Content-Type': 'application/json'
    })
  }), {
    credentials: 'include',
    body: JSON.stringify({
      "hi": 1
    })
  })
  .then(r => console.log)
  .catch(e => console.error)

enter image description here

Topflight answered 2/2, 2017 at 11:24 Comment(1)
Thanks, you were right, it does not make sense to use FormData if I'm body is a json anyway. Thanks.Pneumogastric

© 2022 - 2024 — McMap. All rights reserved.