Nodejs http request 的响应问题

Nodejs http request 的响应问题

同一个服务端接口, 使用nodejs http request请求响应的时间(154ms) 是 在前端使用ajax请求响应时间(15ms)的10倍, 有哪些因素可以导致这样的情况? nodejs 代码如下: request: function (params, call, err, cookie) { if (this.option.isCookieNeeded === true && cookie === undefined) { throw new Error('This request is cookie needed, you must set a cookie for it before request. id = ’ + this.option.id) }

    err = typeof err !== 'function' ? function (e) {
        console.error(e)
    } : err;

    if (this.option.status === STATUS_MOCK || this.option.status === STATUS_MOCK_ERR) {
        this._mock(params, call, err);
        return;
    }

    this.option.method = this.option.method.toLocaleUpperCase();

    var self = this, options = {
        hostname: self.option.hostname,
        port: self.option.port,
        path: self.option.path,
        method: self.option.method,
        headers: {
            Cookie: cookie
        }
    }, querystr;

    if (self.option.method === 'POST') {
        querystr = JSON.stringify(params);
        options.headers['Content-Type'] = 'application/json;charset=utf-8';
    } else if (self.option.method === 'GET') {
        querystr = self._stringify(params);
        options.path += '?' + querystr
    }
    var req = http.request(options, function (res) {
        var timer = setTimeout(function () {
            err(new Error('timeout'))
        }, self.option.timeout || 5000);

        var bufferHelper = new BufferHelper();

        res.on('data', function (chunk) {
            bufferHelper.concat(chunk);
        });

        res.on('end', function () {
            var buffer = bufferHelper.toBuffer(), result;
            try {
                result = self.option.encoding === ENCODING_RAW ? buffer :
                    (self.option.dataType !== 'json' ? iconv.fromEncoding(buffer, self.option.encoding) :
                        JSON.parse(iconv.fromEncoding(buffer, self.option.encoding)))
            } catch (e) {
                clearTimeout(timer);
                err(new Error('The result has syntax error. ' + e));
                return;
            }
            clearTimeout(timer);
            call(result, res.headers['set-cookie'])
        })
    });

    self.option.method !== 'POST' || req.write(querystr);
    req.on('error', function (e) {
        err(e)
    });
    req.end()
},

3 回复

Node.js HTTP 请求响应问题

在Node.js中,HTTP请求的响应时间可能会比前端的AJAX请求慢很多。这可能是由于多种因素造成的,包括但不限于以下几点:

  1. 网络延迟:Node.js运行在一个服务器环境中,通常与前端相比,服务器到目标服务端的距离更远,因此网络延迟更高。
  2. CPU性能:Node.js应用程序可能在性能较低的服务器上运行,从而导致处理时间更长。
  3. 并发处理:Node.js是单线程的,如果当前有大量请求正在处理,新请求可能会排队等待,从而增加响应时间。
  4. 中间件和库的影响:Node.js应用程序中的中间件或第三方库可能会影响性能。

以下是一个简单的示例代码,展示了如何使用Node.js的http模块发送一个HTTP请求,并处理响应。

const http = require('http');
const httpProxy = require('http-proxy');

// 示例函数,用于发送HTTP请求并处理响应
function sendHttpRequest(params, call, err, cookie) {
    // 检查是否需要cookie
    if (this.option.isCookieNeeded && !cookie) {
        throw new Error('This request is cookie needed, you must set a cookie for it before request. id = ' + this.option.id);
    }

    // 设置错误回调
    err = typeof err !== 'function' ? function (e) {
        console.error(e);
    } : err;

    // 处理模拟请求
    if (this.option.status === 'MOCK' || this.option.status === 'MOCK_ERR') {
        this._mock(params, call, err);
        return;
    }

    const method = this.option.method.toUpperCase();
    const options = {
        hostname: this.option.hostname,
        port: this.option.port,
        path: this.option.path,
        method: method,
        headers: {
            Cookie: cookie
        }
    };

    let queryStr;
    if (method === 'POST') {
        queryStr = JSON.stringify(params);
        options.headers['Content-Type'] = 'application/json;charset=utf-8';
    } else if (method === 'GET') {
        queryStr = this._stringify(params);
        options.path += '?' + queryStr;
    }

    const req = http.request(options, (res) => {
        const timer = setTimeout(() => {
            err(new Error('timeout'));
        }, this.option.timeout || 5000);

        const bufferHelper = new BufferHelper();

        res.on('data', (chunk) => {
            bufferHelper.concat(chunk);
        });

        res.on('end', () => {
            const buffer = bufferHelper.toBuffer();
            let result;
            try {
                result = this.option.encoding === 'RAW' ? buffer :
                    (this.option.dataType !== 'json' ? iconv.fromEncoding(buffer, this.option.encoding) :
                        JSON.parse(iconv.fromEncoding(buffer, this.option.encoding)));
            } catch (e) {
                clearTimeout(timer);
                err(new Error('The result has syntax error. ' + e));
                return;
            }
            clearTimeout(timer);
            call(result, res.headers['set-cookie']);
        });
    });

    if (method !== 'POST') {
        req.write(queryStr);
    }

    req.on('error', (e) => {
        err(e);
    });

    req.end();
}

// 示例调用
sendHttpRequest({
    hostname: 'example.com',
    port: 80,
    path: '/api/data',
    method: 'GET',
    timeout: 5000,
    encoding: 'UTF-8',
    dataType: 'json'
}, (result) => {
    console.log('Response:', result);
}, (err) => {
    console.error('Error:', err);
});

在这个示例中,我们定义了一个sendHttpRequest函数来处理HTTP请求。该函数会根据不同的HTTP方法(如GET或POST)构造请求,并处理响应。注意,这里使用了BufferHelper来处理分块数据,确保所有数据都被正确接收并解析。

希望这些信息能帮助你理解为什么Node.js的HTTP请求响应时间可能比前端的AJAX请求长,并提供了一个简单的示例代码来帮助你处理HTTP请求。


怎么都没人回复啊

根据你的描述,Node.js中的HTTP请求响应时间比前端的AJAX请求响应时间长得多。这种情况可能由以下几个因素导致:

  1. 网络延迟:Node.js运行在一个独立的环境中,可能需要通过更远的距离或不同的网络路径来访问服务器,这可能导致更高的网络延迟。

  2. DNS解析时间:如果DNS解析较慢,Node.js可能会花更多时间来解析域名到IP地址。

  3. 进程上下文切换:Node.js作为一个单独的进程运行时,可能会受到操作系统调度的影响,导致额外的上下文切换时间。

  4. 编码和解码开销:你的代码中使用了iconv模块进行字符编码转换,这会增加额外的处理时间。

  5. 异步处理开销:虽然Node.js擅长处理异步操作,但在某些情况下,过多的异步回调可能会增加额外的处理开销。

  6. 系统资源限制:Node.js实例可能受限于系统的文件描述符数量、内存分配等因素,这也可能影响性能。

示例代码优化

以下是简化版的示例代码,移除了iconv模块并使用内置的Buffer处理,以减少不必要的处理开销:

const http = require('http');
const { promisify } = require('util');

const requestAsync = promisify(http.request);

async function makeRequest(params, call, err, cookie) {
    if (this.option.isCookieNeeded && cookie === undefined) {
        throw new Error(`This request is cookie needed, you must set a cookie for it before request. id = ${this.option.id}`);
    }

    const { hostname, port, path, method } = this.option;
    let body = '';

    if (method.toUpperCase() === 'POST') {
        body = JSON.stringify(params);
    } else if (method.toUpperCase() === 'GET') {
        path += `?${new URLSearchParams(params).toString()}`;
    }

    try {
        const response = await requestAsync({
            hostname,
            port,
            path,
            method,
            headers: {
                Cookie: cookie,
                'Content-Type': 'application/json;charset=utf-8'
            }
        }, async (res) => {
            res.setEncoding('utf8');
            res.on('data', (chunk) => {
                body += chunk;
            });

            res.on('end', () => {
                try {
                    const result = this.option.dataType !== 'json' ? body : JSON.parse(body);
                    call(result, res.headers['set-cookie']);
                } catch (e) {
                    err(new Error('The result has syntax error.' + e));
                }
            });
        });

        response.on('error', (e) => {
            err(e);
        });

        response.end();
    } catch (e) {
        err(e);
    }
}

这段代码使用了promisify将回调式的http.request转为Promise风格,使得异步处理更加清晰和简单。同时,减少了不必要的编码转换,直接使用utf8编码处理响应数据。

回到顶部