如何解决NODE.Js HTTP POST“ECONNRESET”错误

7
我有这个函数,当传入下面的数据时会返回ECONNRESET,socket hang up错误。然而,当discountCode数组只有大约10个对象时,它可以无问题地进行POST。
这个问题的原因是什么?我试图通过在Buffer中分段数据来进行多个req.write(),但是那并不好用。任何NodeJs忍者都能给一些关于这个问题的见解吗?
createObj: function(data, address, port, callback) {

//console.log('Create Reward: '+JSON.stringify(data));
var post_data = JSON.stringify(data);

var pathName = '/me/api/v1/yyy/'+data.idBusinessClient+'/newObj';

    // 
    var options = {
        hostname: address,
        port: port,
        path: pathName,
        method: 'POST',
        headers: {
            'Content-Type': 'application/json; charset=utf-8',
            'Accept': 'application/json',
            'Accept-Encoding': 'gzip,deflate,sdch',
            'Accept-Language': 'en-US,en;q=0.8'
        }
    };

    // http call to REST API server
    var req = restHttp.request(options, function(res) {

        console.log('HTTP API server PUT Reward response received.');
        var resData = '';
        res.on('data', function(replyData) {

            // Check reply data for error.
            console.log(replyData.toString('utf8'));
            if(replyData !== 'undefined')
                resData += replyData;
        });

        res.on('end', function() {
            //<TODO>Process the data</TODO>             
            callback(JSON.parse(resData));
        });
    });

    req.write(post_data);
    req.end();

    console.log('write end');

    req.on('close', function() {
        console.log('connection closed!');
    });

    req.on('error', function(err) {
        console.log('http request error : '+err);
        callback({'error':err});
        throw err;
    });

    req.on('socket', function(socket) {
        console.log('socket size:'+socket.bufferSize);
        socket.on('data', function(data) {
            console.log('socket data:'+data);
        });
    });

}

]}`


ECONNRESET 表示服务器由于某种原因关闭了连接。也许它不接受那么多的数据?这是自己编写的服务器 API 还是有文档可用的东西? - Markus
是的,这是使用Java Spring框架编写的自有服务器API。仍在寻找它拒绝数据的原因。你有任何想法吗?;) - Hong Zhou
1
你能在头部添加一个代理:Mozilla和连接:Keep-Alive吗? - Sanjeev
4个回答

9

我遇到了同样的问题,通过添加Content-Length头部来解决它:

    headers: {
        'Content-Type': 'application/json; charset=utf-8',
        'Content-Length': Buffer.byteLength(post_data),
        'Accept': 'application/json',
        'Accept-Encoding': 'gzip,deflate,sdch',
        'Accept-Language': 'en-US,en;q=0.8'
    }

然而,我仍然不清楚为什么缺少Content-Length头会导致如此麻烦。我猜这是Node.js内部代码的某种怪异性。也许你甚至可以称之为一个bug,但我不确定;)
PS:我绝对对这个问题的原因更感兴趣。如果您有任何想法,请留下评论...

这个错误是在我使用豹子 Mac 进行测试时出现的。然而,当我使用一台更新的机器进行测试时,我就不再遇到这样的问题了。并且它在我的目标机器上也没有出现。所以我和你一样感到困惑 :o - Hong Zhou
我遇到了同样的问题。我尝试了你的解决方案,它起作用了!我不知道为什么,如果你有任何想法,请告诉我。谢谢。 - creeper
1
我的问题与请求中的端口有关。尝试使用443进行SSL,但它不起作用。 - Papa Burgundy

1
当您更改响应内容时,确保您还需要在标头上更新内容长度:
headers: {
    ...
    'Content-Length': Buffer.byteLength(post_data),
    ...
}

但是当我尝试进行多个请求时,我也遇到了这个问题,似乎不同的库并没有很好地处理这个问题,因此我发现了一个解决方法,如果这个问题仍然存在,就在头部添加:

headers: {
    ...
    connection: 'Close'
    ...
}

所以,如果您在不同的服务器上进行请求.. 完成进程后关闭连接。在net、node-http-proxy中,这对我有用。

1
如果使用 Expresshttp-proxy-middleware 进行 POST 调用,并且使用了一些请求体解析中间件,比如 express.json(),则必须使用请求拦截器 fixRequestBody更多信息)。否则,POST 调用将会因为 ECONNRESET 错误而挂起。
const express = require('express');
const { createProxyMiddleware, fixRequestBody } = require('http-proxy-middleware');

const app = express();
app.use(express.json());
app.post(
  '/path',
  createProxyMiddleware('/path', {
    target: API_URL,
    changeOrigin: true,
    pathRewrite: (path, req) => `/something/${req?.body?.someParameter}`,
    onProxyReq: fixRequestBody // <- Add this line
  });

0

我曾经遇到过同样的问题。对我来说,解决方案是将其附加到代理中以使其正常工作。如果您没有使用代理,您可能只需将其附加到POST请求本身即可。

使用代理:

import express from 'express';
import { createProxyMiddleware } from 'http-proxy-middleware';
import logger from './logger';

        // setup routes
        server.get('/isAlive', (req, res) => res.send('Alive'));
        server.get('/isReady', (req, res) => res.send('Ready'));

        server.use(express.static(path.join(__dirname, '../build')));

        const restream = (proxyReq, req, res, options) => {
            if (req.body) {
                let bodyData = JSON.stringify(req.body);
                proxyReq.setHeader('Content-Type', 'application/json');
                proxyReq.setHeader('Content-Length', Buffer.byteLength(bodyData));
                proxyReq.write(bodyData);
            }
        };

        server.use(
            '/api',
            createProxyMiddleware({
                target: 'http://your-backendUrl-api',
                onProxyReq: restream,
                changeOrigin: true,
                proxyTimeout: 30000,
                secure: true,
                logLevel: 'info',
                onError: (err, req, res) => {
                    logger.error('error in proxy', err, req, res);
                },
            })
        );

例如,没有代理:

import axios, { AxiosResponse } from 'axios';

const api = axios.create({
    baseURL: '/api/....',
    timeout: 35000,
    withCredentials: true,
    headers: { Pragma: 'no-cache', 'Cache-Control': 'no-cache' },
    validateStatus: (status) => status < 400,
});

    const response = await api.post(
        `/somepath/${exampleInjectedId}/somepathToRestAPI`,
        {
         ...payload
        },
        {
            baseURL: '/api/...',
            timeout: 35000,
            withCredentials: true,
            headers: {
                Pragma: 'no-cache',
                'Cache-Control': 'no-cache',
                'Content-Length': Buffer.byteLength(
                    JSON.stringify({
                        ...payload
                    })
                ),
            },
            validateStatus: (status) => status < 400,
        }
    );

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接