简体   繁体   中英

SyntaxError: Unexpected token " in JSON at position 0

I have an error with request to express. I have this fetch:

fetch(`http://localhost:4200/dist/js/server.min.js`, {
    method: "POST",
    // mode: 'no-cors',
    headers: {
      "Content-Type": "application/json",
    },
    body: JSON.stringify(`<html><body><div style="background-color: yellow;"><p>Hello World!</p></div></body></html>`),
  }).then((response) => {
      console.log(response)
  })

And I have such a code for my express server:

const { exec }   = require("child_process"),
      express    = require("express"),
      bodyParser = require('body-parser'),
      webshot    = require('webshot'),
      PORT       = 4200,
      app        = express(),
      cors       = require('cors')

// app.use(cors())

app.use((req, res, next) => {
    res.append('Access-Control-Allow-Origin', 'http://localhost:4242');
    res.append('Access-Control-Allow-Methods', 'POST', 'GET', 'OPTIONS');
    res.append('Access-Control-Allow-Headers', 'Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With');
    res.append('Access-Control-Allow-Credentials', 'true');
    next();
    
});

// app.use(express.json());
app.use(bodyParser.json());

app.get('/dist/js/server.min.js', (req, res) => {
    res.send('<h1>Hello</h1>')
})

app.post('/', function(req, res) {
    htmlData = req.body
    screen(htmlData) // just my function
});

app.listen(PORT, () => {
    console.log(`What's my age again? ${PORT}, I guess.`)
});

And I've got this error in browser:

POST http://localhost:4200/dist/js/server.min.js 400 (Bad Request)

And this in console:

SyntaxError: Unexpected token " in JSON at position 0
    at JSON.parse (<anonymous>)
    at createStrictSyntaxError (/home/joe/Documents/vscode-projects/html-projects/swipeskins/node_modules/body-parser/lib/types/json.js:158:10)
    at parse (/home/joe/Documents/vscode-projects/html-projects/swipeskins/node_modules/body-parser/lib/types/json.js:83:15)
    at /home/joe/Documents/vscode-projects/html-projects/swipeskins/node_modules/body-parser/lib/read.js:121:18
    at invokeCallback (/home/joe/Documents/vscode-projects/html-projects/swipeskins/node_modules/body-parser/node_modules/raw-body/index.js:224:16)
    at done (/home/joe/Documents/vscode-projects/html-projects/swipeskins/node_modules/body-parser/node_modules/raw-body/index.js:213:7)
    at IncomingMessage.onEnd (/home/joe/Documents/vscode-projects/html-projects/swipeskins/node_modules/body-parser/node_modules/raw-body/index.js:273:7)
    at IncomingMessage.emit (events.js:198:15)
    at endReadableNT (_stream_readable.js:1139:12)
    at processTicksAndRejections (internal/process/task_queues.js:81:17)

I guess, server has problems with parsing json data. But why? What is wrong with code?

Thanks a lot for your time, I would be very grateful to hear something from you if you have some thoughts about my situation.

Your JSON's top level data type is a string:

 JSON.stringify(`<html>...</html>`);

The current version of the JSON specification allows the top level data type in the JSON text to be any JSON data type.

The original version only allowed an object or an array.

The error message says that having " as the first character is an error, which implies that it doesn't support strings as the top level data type (and thus implements the original specification).


Either change the structure of the JSON so it starts with an object or an array:

{
    "html": "<html>...</html>"
}

or change the data format you are sending:

"Content-Type: text/html"

and

 body: "<html>...</html>" // without JSON.stringify

Obviously, you'll need to change the server-side code to accept the changed format.

The problem is that the express JSON body parser by default only accepts inputs that can be parsed as JSON objects . However, you can change it to accept other types of valid JSON data (including strings, like in the OP) by disabling "strict" parsing:

app.use(express.json({strict: false}));

This is the workaround the worked for me.

Reference: https://github.com/expressjs/express/issues/1725#issuecomment-22844485

On request body you are not parsing a DOM element, so you can do the following:

const parser = new DOMParser();
const raw = '<html><body><div style="background-color: yellow;"><p>Hello World!</p></div></body></html>';
const body = parser.parseFromString(raw, 'text/html');

fetch(`http://localhost:4200/dist/js/server.min.js`, {
    method: "POST",
    // mode: 'no-cors', // If you use 'no-cors' you will not get response body and some headers
    headers: {
      "Content-Type": "application/json",
    },
    body: JSON.stringify(body),
  }).then((response) => {
      console.log(response);
  })

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM