SyntaxError: Unexpected token " in JSON at position 0 in stringify

6k views Asked by At

I have seen this question asked a few times here but never with the “ character.

For clarification this is not my code that is putting out the error, this is what I get back from an api.

My first try:

I use https://reqbin.com/ and the request works perfectly (what i did)

My second try:

I decide to move this to running programmatically to use in development.

On ios there is an app called scriptable this allows you to run javascript

docs for their request object

I use the code

let req = new Request("https://support.readaloud.app/ttstool/createParts"); 
req.method = "post"; 
req.headers = {"Content-Type": "application/json" }; 
var data = '[{"voiceId":"Amazon British English (Brian)","ssml":"<speak version=\"1.0\" xml:lang=\"en-GB\">' + "Hello" + '</speak>"}]';
req.body = JSON.stringify(data);
let res = await req.loadString();

Where res should respond with ["id"] like reqbin

Unfortunately it does not and returns

SyntaxError: Unexpected token " in JSON at position 0
    at JSON.parse (<anonymous>)
    at createStrictSyntaxError (/home/ec2-user/readaloud/webservices/node_modules/body-parser/lib/types/json.js:160:10)
    at parse (/home/ec2-user/readaloud/webservices/node_modules/body-parser/lib/types/json.js:83:15)
    at /home/ec2-user/readaloud/webservices/node_modules/body-parser/lib/read.js:128:18
    at AsyncResource.runInAsyncScope (node:async_hooks:201:9)
    at invokeCallback (/home/ec2-user/readaloud/webservices/node_modules/raw-body/index.js:231:16)
    at done (/home/ec2-user/readaloud/webservices/node_modules/raw-body/index.js:220:7)
    at IncomingMessage.onEnd (/home/ec2-user/readaloud/webservices/node_modules/raw-body/index.js:280:7)
    at IncomingMessage.emit (node:events:538:35)
    at endReadableNT (node:internal/streams/readable:1345:12)

If you can help I would greatly appreciate it.

Thanks

3

There are 3 answers

0
Quentin On

The error is caused because the JSON parser is very out of date and doesn't support JSON where the top level data type is a string. (The original spec for JSON only allowed objects and arrays but that was changed to allow any data type).

However, you shouldn't be sending a JSON text where the top level element is a string in the first place.

var data = '[{"voiceId":"Amazon British English (Brian)","ssml":"<speak version=\"1.0\" xml:lang=\"en-GB\">' + "Hello" + '</speak>"}]';

Here you are manually constructing a string of JSON (although it has errors in it because some quotes are not properly escaped).

req.body = JSON.stringify(data);

And then you create a string of JSON representing the previous string.


Don't do that. Create a regular JavaScript data structure (i.e. an array), not a string.

Then convert the array to JSON with JSON.stringify.

I also recommend applying the same principles to XML creation (i.e. don't mash strings together).


const doc = document.implementation.createDocument(null, "speak");
const speak = doc.documentElement;
speak.setAttribute("version", "1.0");
speak.setAttribute("xml:lang", "en-GB");
speak.appendChild(doc.createTextNode("Hello"));
const xml = new XMLSerializer().serializeToString(speak);
const data = [{
  voiceId: "Amazon British English (Brian)",
  ssml: xml
}];
const json = JSON.stringify(data);
console.log(json);

0
Diki Agustin On

try to set variable without quote, and fix it a bit so it becomes like this

var data = [{"voiceId":"Amazon British English (Brian)","ssml":"<speak version=\"1.0\" xml:lang=\"en-GB\">Hello</speak>" }];
0
Trishant Pahwa On
let req = new Request("https://support.readaloud.app/ttstool/createParts"); 
req.method = "POST"; 
req.headers = {"Content-Type": "application/json" }; 
var data = [
    {
        "voiceId":"Amazon British English (Brian)",    
        "ssml":"<speak version=\"1.0\" xml:lang=\"en-GB\">" + "Hello" + "</speak>"
}]
req.body = JSON.stringify(data);
let res = await req.loadString();
console.log(res);