Node.js 和 Express - BadRequestError:请求中止

问题描述 投票:0回答:3

我正在对我创建的node.js api 进行性能测试。

有一个 POST 端点,它将图像作为 base64 的输入。所以请求有效负载相当大,我的测试用例图像约为 7-8mb。

当我同时对 10 个用户运行性能测试时,出现以下错误:

请求

{"log_id":"db0ac1d0-cafe-11e9-afec-e91ff7e323e3","level":"info","request":{"method":"POST","path":"<removed>","url":"<api_url_removed>","body":{},"forward_for":"<removed>","content_type":"application/json","content_length":"7687038"},"message":"Received","log_type":"request","timestamp":"2019-08-30 08:19:15"}

错误:

BadRequestError:请求中止 在 IncomingMessage.onAborted (/app/node_modules/raw-body/index.js:231:10) 在 IncomingMessage.emit (events.js:189:13) 在 abortIncoming (_http_server.js:449:9) 在 socketOnClose (_http_server.js:442:3) 在 Socket.emit (events.js:194:15) 在 TCP._handle.close (net.js:600:12)

我可以看到其中 10-20 个请求出现相同的错误。他们都有独特的 ID。显然,因为我正在运行性能测试,所以发出这么多请求是正常的。

我的问题是为什么 node.js/express 会抛出这个 BadRequestError 以及我该如何处理它。

app.ts

class App {

    public app: express.Application;
    public config: any;
    public log = Logger;

    constructor() {

        this.app = express();

        this.errors();
        this.environment();
        this.database();
        this.middleware();
        this.routes();

    }

    private environment(): void {

        this.config = new Config();

    }

    private errors(): void {

        // TODO: Remove ( Handled By Winston );
        // process.on("uncaughtException", (ex) => {
        //     process.exit(1);
        // });

        process.on("unhandledRejection", (ex) => {
            throw ex;
        });


    }

    private database(): void {

        const uri: string = this.config.db.uri;
        const options: mongoose.ConnectionOptions = this.config.db.options;

        mongoose.connect(uri, options).then(
            () => {
                this.log.info("MongoDB Successfully Connected On: " + this.config.db.uri);
            },
            (err: any) => {
                this.log.error("MongoDB Error:", err);
                this.log.info("%s MongoDB connection error. Please make sure MongoDB is running.");
                throw err;
            },

        );

    }

    private middleware(): void {

        const logs = new LogMiddleware(this.app);

        this.app.use(cors());

        this.app.use(morgan("combined", {

            skip: (req, res) => {
                return (req.originalUrl === "/api/v2/healthcheck") ? true : false;
            },
            stream: {
                write: (meta: any) => {
                },
            },
        }));

        this.app.use(express.json({limit: "16mb"}));
        this.app.use(express.urlencoded({ limit: "16mb", extended: true, parameterLimit: 50000 }));
        this.app.use(passport.initialize());


    }

    private routes(): void {

        const routes = new Routes(this.app);
    }

}

export default App;
node.js express
3个回答
0
投票

当客户端在服务器处理完请求之前断开连接时,Node.js 和 Express 中通常会发生

BadRequestError: request aborted
错误。发生这种情况的原因有多种,处理方法如下:

可能原因及解决方案

  1. 网络问题
    如果客户端的网络连接不稳定或中断,请求可能会在到达服务器之前被中止。确保您的网络连接稳定。

  2. 请求大小和正文解析
    如果您使用

    body-parser
    或其他中间件,则可能会出现处理大负载的问题。尝试增加请求正文限制以处理更大的负载:

    const express = require('express');
    const bodyParser = require('body-parser');
    const app = express();
    
    // Increase limit as needed
    app.use(bodyParser.json({ limit: '10mb' }));
    app.use(bodyParser.urlencoded({ extended: true, limit: '10mb' }));
    
  3. 优雅地处理中止的请求
    添加事件侦听器来处理中止的请求,这样它们就不会导致未捕获的错误:

    app.use((req, res, next) => {
        req.on('aborted', () => {
            console.error('Request was aborted by the client');
        });
        next();
    });
    
  4. 反向代理超时(如果适用)
    如果您使用 Nginx 等反向代理,如果请求时间过长或超出有效负载大小限制,它可能会终止连接。检查您的代理设置以确保它们不会导致请求中止。


-3
投票

此问题与 body-parser 包设置有关

这是文档中提到的基本设置

var express = require('express')
var bodyParser = require('body-parser')

var app = express()

// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))

// parse application/json
app.use(bodyParser.json())

app.use(function (req, res) {
  res.setHeader('Content-Type', 'text/plain')
  res.write('you posted:\n')
  res.end(JSON.stringify(req.body, null, 2))
})

您还可以在此处找到代码的链接添加通用 JSON 和 URL 编码


-3
投票

我认为您希望应用程序以以下方式启动:

this.app = express();

this.errors();
this.environment();
this.database();
this.middleware();
this.routes();

Node.js 具有异步特性,数据库连接进行 I/O 操作时会执行最后一次操作。在建立数据库连接之前,您的应用程序很可能已经开始处理请求。因此,在某些控制器/路由中,您会抛出 400 错误。

您需要做的是在连接并运行所有烘焙服务(例如数据库)后启动应用程序。

© www.soinside.com 2019 - 2024. All rights reserved.