网易首页 > 网易号 > 正文 申请入驻

深入理解nodejs的HTTP处理流程

0
分享至

简介

我们已经知道如何使用nodejs搭建一个HTTP服务,今天我们会详细的介绍nodejs中的HTTP处理流程,从而对nodejs的HTTP进行深入的理解。

使用nodejs创建HTTP服务

使用nodejs创建HTTP服务很简单,nodejs提供了专门的HTTP模块,我们可以使用其中的createServer方法来轻松创建HTTP服务:

const http = require('http');

const server = http.createServer((request, response) => {
// magic happens here!
});

首先createServer方法传入的是一个callback函数,这个callback函数将会在每次服务端接收到客户端的请求时调用。所以这个callback函数,也叫做 request handler.

再看看createServer的返回值,createServer返回的是一个EventEmitter对象。

之前我们也介绍过了EventEmitter,它可以发送和接收事件,所以我们可以使用on来监听客户端的事件。

上面的代码相当于:

const server = http.createServer();
server.on('request', (request, response) => {
// the same kind of magic happens here!

当发送request事件的时候,就会触发后面的handler method,并传入request和response参数。我们可以在这个handler中编写业务逻辑。

当然,为了让http server正常运行,我们还需要加上listen方法,来绑定ip和端口,以最终启动服务。

const hostname = '127.0.0.1'
const port = 3000

server.listen(port, hostname, () => {
console.log(`please visit http://{hostname}:{port}/`)
})

解构request

上面的request参数实际上是一个http.IncomingMessage对象,我们看下这个对象的定义:

class IncomingMessage extends stream.Readable {
constructor(socket: Socket);

aborted: boolean;
httpVersion: string;
httpVersionMajor: number;
httpVersionMinor: number;
complete: boolean;
/**
* @deprecate Use `socket` instead.
*/
connection: Socket;
socket: Socket;
headers: IncomingHttpHeaders;
rawHeaders: string[];
trailers: NodeJS.Dict;
rawTrailers: string[];
setTimeout(msecs: number, callback?: () => void): this;
/**
* Only valid for request obtained from http.Server.
*/
method?: string;
/**
* Only valid for request obtained from http.Server.
*/
url?: string;
/**
* Only valid for response obtained from http.ClientRequest.
*/
statusCode?: number;
/**
* Only valid for response obtained from http.ClientRequest.
*/
statusMessage?: string;
destroy(error?: Error): void;
}

通常我们需要用到request中的method,url和headers属性。

怎么从request中拿到这些属性呢?对的,我们可以使用ES6中解构赋值:

const { method, url } = request;

const { headers } = request;
const userAgent = headers['user-agent'];

其中request的headers是一个IncomingHttpHeaders,它继承自NodeJS.Dict。

处理Request Body

从源码可以看出request是一个Stream对象,对于stream对象来说,我们如果想要获取其请求body的话,就不像获取静态的method和url那么简单了。

我们通过监听Request的data和end事件来处理body。

let body = [];
request.on('data', (chunk) => {
body.push(chunk);
}).on('end', () => {
body = Buffer.concat(body).toString();
// at this point, `body` has the entire request body stored in it as a string

因为每次data事件,接收到的chunk实际上是一个Buffer对象。我们将这些buffer对象保存起来,最后使用Buffer.concat来对其进行合并,最终得到最后的结果。

直接使用nodejs来处理body看起来有点复杂,幸运的是大部分的nodejs web框架,比如koa和express都简化了body的处理。
处理异常

异常处理是通过监听request的error事件来实现的。

如果你在程序中并没有捕获error的处理事件,那么error将会抛出并终止你的nodejs程序,所以我们一定要捕获这个error事件。

request.on('error', (err) => {
// This prints the error message and stack trace to `stderr`.
console.error(err.stack);
解构response

response是一个http.ServerResponse类:

class ServerResponse extends OutgoingMessage {
statusCode: number;
statusMessage: string;

constructor(req: IncomingMessage);

assignSocket(socket: Socket): void;
detachSocket(socket: Socket): void;
// https://github.com/nodejs/node/blob/master/test/parallel/test-http-write-callbacks.js#L53
// no args in writeContinue callback
writeContinue(callback?: () => void): void;
writeHead(statusCode: number, reasonPhrase?: string, headers?: OutgoingHttpHeaders): this;
writeHead(statusCode: number, headers?: OutgoingHttpHeaders): this;
writeProcessing(): void;
}

对于response来说,我们主要关注的是statusCode:

response.statusCode = 404;

Response Headers:

response提供了setHeader方法来设置相应的header值。

response.setHeader('Content-Type', 'application/json');
response.setHeader('X-Powered-By', 'bacon');

还有一个更加直接的同时写入head和status code:

response.writeHead(200, {
'Content-Type': 'application/json',
'X-Powered-By': 'bacon'

最后,我们需要写入response body,因为response是一个WritableStream,所以我们可以多次写入,最后以end方法结束:

response.write('');
response.write('');
response.write('Hello, World!');
response.write('');
response.write('');
response.end();

或者我们可以用一个end来替换:

response.end('Hello, World!');

综上,我们的代码是这样的:

const http = require('http');

http.createServer((request, response) => {
const { headers, method, url } = request;
let body = [];
request.on('error', (err) => {
console.error(err);
}).on('data', (chunk) => {
body.push(chunk);
}).on('end', () => {
body = Buffer.concat(body).toString();
// BEGINNING OF NEW STUFF

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

response.statusCode = 200;
response.setHeader('Content-Type', 'application/json');
// Note: the 2 lines above could be replaced with this next one:
// response.writeHead(200, {'Content-Type': 'application/json'})

const responseBody = { headers, method, url, body };

response.write(JSON.stringify(responseBody));
response.end();
// Note: the 2 lines above could be replaced with this next one:
// response.end(JSON.stringify(responseBody))

// END OF NEW STUFF
});
}).listen(8080);

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
金球奖这一夜,国际女星个个风情万种,但都被一位中国女星艳压了

金球奖这一夜,国际女星个个风情万种,但都被一位中国女星艳压了

八卦南风
2026-01-12 16:25:50
贾玲巴黎周“一脸男相”!不爱笑也没梨涡眼神犀利,梳大背头好酷

贾玲巴黎周“一脸男相”!不爱笑也没梨涡眼神犀利,梳大背头好酷

轩逸阿II
2026-01-20 07:54:29
12斤肉3个月甩净!全红婵减重到离谱,这哪是减肥,是拿命拼金牌

12斤肉3个月甩净!全红婵减重到离谱,这哪是减肥,是拿命拼金牌

做一个合格的吃瓜群众
2025-12-31 07:41:05
泰国等严查柬埔寨入境中国籍人员

泰国等严查柬埔寨入境中国籍人员

原某报记者
2026-01-19 14:00:13
94岁胡枫寿宴变明星演唱会!四个曾孙相伴,张学友下跪谢恩太炸裂

94岁胡枫寿宴变明星演唱会!四个曾孙相伴,张学友下跪谢恩太炸裂

一盅情怀
2026-01-20 14:37:45
韩网友提问:在铁证面前,中国人为什么还不承认汉字起源于韩国?

韩网友提问:在铁证面前,中国人为什么还不承认汉字起源于韩国?

芳芳历史烩
2026-01-20 20:53:46
宋骧曝梁小龙死因,凌晨胸痛,去医院神志清醒,一个举动害了他

宋骧曝梁小龙死因,凌晨胸痛,去医院神志清醒,一个举动害了他

观察鉴娱
2026-01-20 10:12:36
湖北女子花60块买水果,老公怪她大手大脚,网友:不要花穷人的钱

湖北女子花60块买水果,老公怪她大手大脚,网友:不要花穷人的钱

心轩专栏
2026-01-19 23:36:38
张家辉梁家辉亮相米兰时装周展现独特绅士风度

张家辉梁家辉亮相米兰时装周展现独特绅士风度

孤傲何妨初
2026-01-21 01:59:04
谁是如今欧洲最强的国家?法国:全世界都只有三个比我强

谁是如今欧洲最强的国家?法国:全世界都只有三个比我强

西府赵王爷
2024-07-06 10:54:36
萨莉亚,我劝你别太离谱

萨莉亚,我劝你别太离谱

餐观局
2026-01-19 21:16:06
很多人以为殉葬就是把活人关进地宫,门一关,他们只能哭喊着等死

很多人以为殉葬就是把活人关进地宫,门一关,他们只能哭喊着等死

忠于法纪
2026-01-18 17:42:24
向华炎灵堂现争议,孙女当众大笑,77岁向华强披麻戴孝反差刺眼

向华炎灵堂现争议,孙女当众大笑,77岁向华强披麻戴孝反差刺眼

银河史记
2026-01-20 19:14:27
杭州百岁夫妻,同年同月同日生!一个爱吃糖,一个爱喝酒,不吃保健品,不管闲事

杭州百岁夫妻,同年同月同日生!一个爱吃糖,一个爱喝酒,不吃保健品,不管闲事

极目新闻
2026-01-20 12:30:27
考古王菲李亚鹏的微博,竟然诡异的磕到了

考古王菲李亚鹏的微博,竟然诡异的磕到了

金牌舆情官
2026-01-20 21:19:04
去了北京才发现:没人穿大衣、皮草,满大街都是“海淀风3件套”

去了北京才发现:没人穿大衣、皮草,满大街都是“海淀风3件套”

小虎新车推荐员
2026-01-13 11:24:22
“迷人”的愚蠢——反智盛行的五大原因

“迷人”的愚蠢——反智盛行的五大原因

听哲学
2026-01-18 21:44:12
向余望赛后庆祝:不贪心,再赢一场就回家

向余望赛后庆祝:不贪心,再赢一场就回家

懂球帝
2026-01-21 02:19:12
她因身材发育过猛,无奈退出国家游泳队,被三流导演看中捧成顶流

她因身材发育过猛,无奈退出国家游泳队,被三流导演看中捧成顶流

卿子书
2025-12-31 08:15:41
回顾许家印被抓捕现场,奋力反抗,怒吼不已,被抓捕人员抬出去

回顾许家印被抓捕现场,奋力反抗,怒吼不已,被抓捕人员抬出去

干史人
2026-01-08 22:47:00
2026-01-21 02:39:00
flydean程序那些事
flydean程序那些事
最通俗的解读,最深刻的干货!
356文章数 438关注度
往期回顾 全部

科技要闻

收藏|这可能是CES2026最清醒一份复盘

头条要闻

丹麦首相:主权不谈判 准备贸易战

头条要闻

丹麦首相:主权不谈判 准备贸易战

体育要闻

勇士遭暴击!巴特勒重伤赛季报销

娱乐要闻

网红版闫学晶!600万粉博主阿爆翻车

财经要闻

李迅雷:2026买房不如租房

汽车要闻

奇瑞张贵兵:墨甲不做秀技术的企业 只做痛点终结者

态度原创

时尚
本地
房产
亲子
手机

冬季不臃肿穿搭指南来了,奔五奔六照着穿,拿捏温暖与高级感

本地新闻

云游辽宁|漫步千年小城晨昏,“康”复好心情

房产要闻

中旅・三亚蓝湾发布会揭秘自贸港好房子高阶形态

亲子要闻

这是真的先天法医圣体阿!

手机要闻

iQOO 15 Ultra跑分出炉:451万行业最高记录

无障碍浏览 进入关怀版