14

I'm trying to do http request from nodeJS, this is the following request:

    const form = new FormData();
    form.append('text 1', 'sometext');
    form.append('file', fs.createReadStream("foo.txt"));
    fetch('url', {
            method: 'POST',
            headers: {
                'Content-Type': 'multipart/form-data'
            },
            body: form,
        })
        .then(res => res.json())
        .then(json => {
            console.log('res', json);
        }).catch(err => {
            console.error(err);
            return ReE(res, err.message, 500);
        });

})

But I'm getting the the following error

"error": "invalid json response body at reason: Unexpected token < in JSON at position 0"

What Am I doing wrong?

User100696
  • 687
  • 4
  • 12
  • 26

2 Answers2

18

Try res => console.log(res) in your first .then() block to see what the response is. Usually that error "Unexpected token < in JSON..." means that the response returned some html and the "<" in the error is an opening tag.

joshuamango
  • 221
  • 2
  • 5
  • 1
    tldr: make sure your URL and method are correct. The error described by OP `Unexpected token < in JSON at position 0` may results from requesting a resource that does not exist (typo in the URL?), resulting in express app responding with HTML not JSON. – DeBraid Aug 18 '21 at 19:39
  • What if I don't care that it's not json. Ex a logout URI? – Dragas Aug 04 '23 at 10:41
16

The body is consumed after calling .json(), not sure you can access it afterwards. A simple workaround: get the raw body and parse it yourself:

async function safeParseJSON(response) {
    const body = await response.text();
    try {
        return JSON.parse(body);
    } catch (err) {
        console.error("Error:", err);
        console.error("Response body:", body);
        // throw err;
        return ReE(response, err.message, 500)
    }
}

const json = await = fetch(...).then(safeParseJSON)
tokland
  • 66,169
  • 13
  • 144
  • 170
  • Wouldn't it be helpful if the library added the text into the exception object when doing `response.json()` instead of forcing all code to do this 2 step response.text() -> JSON.parse(). – toddcscar Feb 08 '23 at 01:26