购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

1.1 Node中的请求与响应对象

在Node应用中,请求和响应对象是处理HTTP请求和发送HTTP响应的核心工具,主流框架如Express、Koa、Nest、Egg都实现了不同抽象级别的中间件。本节将开始学习这些内容。

1.1.1 原生Node处理HTTP请求

在Node的内置HTTP模块中有两个核心对象:请求对象(Request)和响应对象(Response)。请求对象表示客户端向服务端发送的请求信息,而响应对象则表示服务端向客户端返回的响应数据。

请求对象通常在客户端发送请求到服务端的过程中使用,携带的信息包含URL、请求方式、请求头、请求体等。常见的属性和方法说明如下。

● req.url:包含客户端请求的URL,不包括协议、主机名和端口号。

● req.method:包含客户端使用的HTTP请求方法,例如GET、POST等。

● req.headers:一个包含所有请求头的对象,可以通过属性名访问具体的请求头信息。

● req.params:包含路由中匹配的参数,对于包含参数的路由非常有用。

● req.query:包含URL查询参数的对象,用于解析URL中的键-值对(Key-Value Pair)。

● req.body:对于POST请求,包含请求体的数据。在Express中需要使用中间件(例如body-parser)来解析请求体。

相反,响应对象是向客户端发送的HTTP响应,设置响应状态、响应头和响应体等信息。常见的属性和方法说明如下。

● res.status(code):设置HTTP响应状态码。

● res.setHeader(name, value):设置响应头的值。

● res.send(body):发送响应体内容给客户端,可以是字符串、JSON对象、缓冲区等。

● res.json(obj):发送JSON格式的响应体给客户端。

● res.sendFile(path, options, callback):发送文件作为响应。

● res.cookie(name, value, option]):设置Cookie信息。

由此可见,Node提供了非常丰富的基础API操作对象,但也带来了一些问题,例如开发者需要关注如何正确处理客户端发送过来的请求数据。请看下面的示例。

原生Node处理请求URL代码示例:

     const http = require("http");
     const url = require("url");

     const server = http.createServer((req, res) => {
       // 解析请求的URL
       const parsedUrl = url.parse(req.url, true);

       // 获取路径和查询参数
       const path = parsedUrl.pathname;
       const queryParams = parsedUrl.query;

       // 设置响应头
       res.writeHead(200, { "Content-Type": "text/plain" });
       res.end(`Path: ${path}, Query Parameters: ${JSON.stringify(queryParams)}`);
     });

     const PORT = 3000;
     server.listen(PORT, () => {
       console.log(`Server is listening on port ${PORT}`);
     });

原生Node处理请求体代码示例:

从上述代码可以看出,Node的原生HTTP模块在处理请求URL时,需要使用Node内置的url模块中的url.parse方法进行解析。如果是POST请求,则需要通过JSON.parse方法来解析请求体。在构造响应时,每个请求都需要设置响应头,最终通过send方法完成发送操作。显然,这种方法在实际的生产开发中显得相当烦琐。

1.1.2 Express处理HTTP请求

然而,Express的诞生简化并抽象了HTTP模块,提供了更加灵活的路由系统。结合中间件,它使得路由的定义和处理变得更加简单。请看下面的例子。

Express处理请求URL代码示例:

Express处理请求体代码示例:

从上述代码可以看出,在Express中,GET请求方式可以直接通过req对象获取对应参数。对于POST请求,通过设置路由中间件,express.json()用于解析请求体中的JSON数据,而express.urlencoded()则用于处理请求体中的URL编码参数,从而简化了烦琐的数据转换操作。

此时,Express的优势已经显而易见。然而,这还不是全部。除了提供强大的路由系统和中间件之外,它还集成了模板引擎、静态文件服务、错误处理机制等功能。但这并不是本书的重点,这里不作过多扩展,感兴趣的读者可以自行了解。

既然Express拥有如此多的优势,Nest又是凭借什么在市场中占据一席之地呢?答案是它解决了架构问题。

再来看Express的路由管理,它可能是这样的:

有经验的读者可能会发现,这种方式的可维护性太差了,于是有了下面的路由管理方式。在主应用中使用模块化管理路由,代码如下:

显然,在对比之下,第二种方式的可维护性和扩展性更高。存在这种差异的原因在于Express没有规定开发者必须遵循哪种方式编写代码。开发者之间的水平不一致导致了这种差异化。从设计者的角度来看,这显然是不可接受的。因此,更高层次的框架——Nest应运而生。

1.1.3 Nest处理HTTP请求

在Nest中是如何处理请求的呢?下面一起来看看。

Nest处理请求URL代码示例:

Nest处理请求体代码示例:

是不是简单多了?没错,这就是在Nest中处理请求的常用方式。它提供了强大的装饰器来操作请求头数据,并且自动判断返回的数据类型来设置合理的Content-type,使得请求处理变得非常灵活。

至此,回顾一下开篇的问题:原生HTTP模块、Express与Nest之间有何联系?相信到这里读者已经有了答案,至于Nest是如何解决架构问题的,会在后续的章节中详细讲解。 Q6LaoNYMQm/khpFWjBqIxOpt5sDXzPSb4ZB7cWpptku9jLjWAybAvAGuQ2AYJXqw

点击中间区域
呼出菜单
上一章
目录
下一章
×