Node.js - 处理正文解析器无效 JSON 错误

Node.js - Handle body-parser invalid JSON error

我正在使用这样的 body-parser 包:

// For parsing application/json:
app.use(require('body-parser').json());

// For parsing application/x-www-form-urlencoded
app.use(require('body-parser').urlencoded({ extended: true })); 

当收到像 { "foo": "bar" } 这样的有效输入时,一切正常,我可以使用 req.body.

访问已解析的对象

但是,当发送无效(非JSON)数据时:

data: JSON.stringify("just something inappropriate"),

我收到这个错误:

{ SyntaxError: Unexpected token " in JSON at position 0
    at JSON.parse (<anonymous>)
    at createStrictSyntaxError
    at ...
expose: true,
statusCode: 400,
status: 400,
body: '"Something"',
type: 'entity.parse.failed' }

Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client at ...

如何正确处理这个问题以防止服务器关闭?

添加一个错误处理程序,然后自定义处理该错误的默认方式的行为,默认情况下会按照您的描述崩溃。

app.use((err, req, res, callback) => {
  // todo: implement error handling logic and return an appropriate response
  console.error(err)
  res.send(500)
  callback()
})

一个选项是添加一个自定义 error handler middleware 并添加一个检查来捕捉 JSON 像这样的解析错误:

app.use(require('body-parser').json()); 
app.use(require('body-parser').urlencoded({ extended: true }));

...

app.use((err, req, res, next) => {
    // This check makes sure this is a JSON parsing issue, but it might be
    // coming from any middleware, not just body-parser:

    if (err instanceof SyntaxError && err.status === 400 && 'body' in err) {
        console.error(err);
        return res.sendStatus(400); // Bad request
    }

    next();
});

另一种选择是包装 body-parser 的中间件以捕获仅来自那里的错误:

const bodyParser = require('body-parser');

app.use((req, res, next) => {
    bodyParser.json()(req, res, err => {
        if (err) {
            console.error(err);
            return res.sendStatus(400); // Bad request
        }

        next();
    });
});

或者如果你想重用这个功能来捕获来自不同中间件的不同错误,你可以这样做:

function handleError(middleware, errorHandler) {
    middleware(req, res, err => err ? errorHandler(err, req, res, next) : next());
}

const bodyParser = require('body-parser');

app.use(handleError(bodyParser.json(), (err, req, res, next) => {
    if (err) {
        console.error(err);
        return res.sendStatus(400); // Bad request
    }

    next();
}));

从 Express 4.16.0 开始 - 发布日期:2017-09-28 您可以捕获来自不同中间件的不同错误,将错误处理程序拆分为不同的函数,而无需使用 Bodyparser,因为它已被弃用。

const app = express();

function handleError(middleware, req, res, next) {
  middleware(req, res, (err) => {
    if (err) {
      console.error(err);
      return res.sendStatus(400); // Bad request
    }

    next();
  });
}

app.use((req, res, next) => {
  handleError(express.json(), req, res, next);
});

注意 Express 4.16.0 及更高版本的代码表示:

 app.use(express.json()); // Without middleware error handling.

替换正文解析器:

 app.use(bodyParser.json()); // Without middleware error handling.

我可能来不及回答这个问题,但让我放在这里吧。 我也收到了这些错误:

SyntaxError: Unexpected token / in JSON at position 11

我发现当我请求json喜欢

{    
    //"name":"Tanjiro",
    "username":"tan_jiro",
    "password":"tan@jiro"
}

直到那时它才给我这个错误。如果我只要求使用,

{    
    "username":"tan_jiro",
    "password":"tan@jiro"
}

它没有给我任何错误。所以看起来错误与请求的完成方式有关,而不是 bodyparser.json()。 谢谢。

body-parser 引发了多种错误。它们涉及发送错误的 headers 或它不接受的数据,或者在读取所有数据之前取消请求。

如果您想要涵盖所有这些错误(包括您提到的错误)的强大解决方案,请使用此中间件

https://www.npmjs.com/package/express-body-parser-error-handler

$ npm i express-body-parser-error-handler

并在 body-parser 初始化后立即放置它

用法示例:

const bodyParserErrorHandler = require('express-body-parser-error-handler')
const { urlencoded, json } = require('body-parser')
const express = require('express')
const app = express();
router.route('/').get(function (req, res) {
    return res.json({message:""});
});

// body parser initilization
app.use(urlencoded({extended: false, limit: defaultLimitSize}));
app.use('/', json({limit: '250'}));

// body parser error handler
app.use(bodyParserErrorHandler());
app.use(router);
...