node.js路由

文章目录


1、node.js路由

1. 什么是路由

  1. 在Web开发中,路由是一个重要的概念。它用于将URL映射到相应的处理程序或控制器,以便处理客户端的请求。
  2. 在 Node.js 中,路由是处理 HTTP 请求的关键部分,它决定了如何根据不同的 URL 和 HTTP 方法(如 GET、POST、PUT、DELETE 等)来分发请求。
  3. 路由通常用于构建 Web 应用程序,特别是 RESTful API。
  4. Node.js 本身并没有内置的路由机制,可以通过中间件库(如 Express)来实现。

路由通常涉及以下几个方面:

  • URL 匹配:根据请求的 URL 来匹配路由规则。
  • HTTP 方法匹配:根据请求的 HTTP 方法(GET、POST、PUT、DELETE 等)来匹配路由规则。
  • 请求处理:一旦匹配到合适的路由规则,就调用相应的处理函数来处理请求。

2. node.js路由的工作原理

node.js路由的工作原理可以分为以下步骤

  1. 请求处理:当服务器接收到一个请求时,它会解析请求的 URL 和 HTTP 方法。
  2. 路由匹配:服务器会根据请求的 URL 和 HTTP 方法,在路由表中查找匹配的路由。
  3. 执行处理函数:找到匹配的路由后,服务器会执行与该路由关联的处理函数。
  4. 发送响应:处理函数执行完毕后,服务器会向客户端发送响应。

2、在node.js中,内置模块实现路由

1.案例

在Node.js中,可以使用内置的http模块来创建简单的服务器,并且处理路由。

javascript 复制代码
const http = require('http');
const port = 3001
// 创建服务器并定义路由
const server = http.createServer((req, res) => {
  const { url, method } = req;
  res.statusCode = 200
    res.setHead({ 'Content-Type': 'text/plain' });
    res.end('Home Page');
});

server.listen(port, () => {
  console.log('Server is running on http://localhost:' + port);
});

2.createServer()

createServer() 用于创建一个 Web 服务器

访问 Node.js 的 GitHub 仓库:https://github.com/nodejs/node

  1. 源码存于lib/http.js文件中,内部就一行代码,实例化一个 Server 类,如下图。
  2. Server 类的实现存于lib/_http_server.js文件中,由源码可知,http.Server 继承自 net.Server,而 net 模块可创建基于流的 TCP 和 IPC 服务器。
  3. http.createServer() 在实例化 net.Server 的过程中,会监听 request 和 connection 两个事件。

3.end()

很多时候写入流是不需要手动调用 end() 方法来关闭的。但如果在读取期间发生错误,那就不能关闭写入流,发生内存泄漏。

为了防止这种情况发生,可监听可读流的错误事件,手动关闭,如下所示。

javascript 复制代码
	readable.on('error', function(err) {
	  writeable.close();
	});

接下来看一种网络场景,改造一下之前的示例,让可读流监听 data、end 和 error 事件,当读取完毕或出现错误时关闭可写流。

javascript 复制代码
const http = require('http');
const port = 3001
var fs = require("fs");
http.createServer((req, res) => {
	// 创建一个可读流
  const readable = fs.createReadStream(__dirname + '/data.txt')
  // 处理流事件 --> data, end, and error
  // data    当有数据可读时触发。
  // end    没有更多的数据可读时触发。
  // error   在接收和写入过程中发生错误时触发。
  // finish  所有数据已被写入到底层系统时触发。
  readable.on('data', chunk => {
    console.log(chunk)
    res.write(chunk);
  });
  readable.on('end',() => {
    res.end('File END');
  })
  readable.on('error', err => {
    console.log(err)
    res.end('File not found');
  });
  readable.on('finish', err => {
    res.end('File finish');
  });
}).listen(port, () => {
  console.log('Server is running on http://localhost:' + port);
})

若不手动关闭,页面将一直处于加载中,在KOA源码中,多处调用了此方法。

注意,若取消对 data 事件的监听,那么页面也会一直处于加载中,因为流一开始是静止的,只有在注册 data 事件后才会开始活动。

4.listen()

listen() 方法用于监听端口,它就是 net.Server 中的 server.listen() 方法。

javascript 复制代码
ObjectSetPrototypeOf(Server.prototype, net.Server.prototype);

5.req 和 res

实例化 Server 时的 requestListener() 回调函数中有两个参数 req(请求对象) 和 res(响应对象)。

  1. 通过 TCP 协议传输过来的二进制数据,会被 http_parser 模块解析成符合 HTTP 协议的报文格式。
  2. 在将请求首部解析完毕后,会触发一个 parserOnHeadersComplete() 回调函数,在回调中会创建http.IncomingMessage 实例,也就是 req 参数。
  3. 而在这个回调的最后,会调用 parser.onIncoming() 方法,在这个方法中会创建 http.ServerResponse 实例,也就是 res 参数。
  4. 最后会触发在实例化 Server 时注册的 request 事件,并将 req 和 res 两个参数传递到 requestListener() 回调函数中。

3、请求参数

  1. 路径解析
    可以使用 URL 对象和 querystring 模块,解析参数。
    用URL对象解析参数在node全局对象一文中有介绍
  • querystring 模块
    querystring 模块用于处理 URL 查询字符串和 POST 请求的数据。

    • querystring.parse()方法解析字符串为一个对象。

      javascript 复制代码
      	const querystring = require('querystring');
      	const str = 'foo=bar&abc=xyz&abc=123';
      	const obj = querystring.parse(str);
      	console.log(obj);   // { foo: 'bar', abc: [ 'xyz', '123' ] }
    • querystring.stringify() 方法序列化一个对象为一个字符串。

      javascript 复制代码
      	const querystring = require('querystring');
      	const obj = { foo: 'bar', abc: [ 'xyz', '123' ] };
      	const str = querystring.stringify(obj);
      	console.log(str); // foo=bar&abc=xyz&abc=123
    • querystring.escape() 和 querystring.unescape() 方法来对和解码URL组件。

      javascript 复制代码
      const querystring = require('querystring');
      const str = 'Hello World!';
      const escapedStr = querystring.escape(str);
      console.log(escapedStr); // Hello%20World!
      const unescapedStr = querystring.unescape(escapedStr);
      console.log(unescapedStr); // Hello World!
  • server.js封装
    server.js文件定义了服务器的启动逻辑,并在接收到请求时调用路由函数。

    javascript 复制代码
    const http = require('http');
    var { URL } = require("url");
    const port = 3001
    // 创建服务器并定义路由
    function server(route) {
      const server = http.createServer((req, res) => {
        const { url, method } = req;
        const pathname = new URL(req.url, `http://${req.headers.host}`).pathname
        route(pathname, method); 
        // 设置响应头和响应内容
        res.writeHead(200, { 'Content-Type': 'text/plain' });
        res.write('Start1 Page'); // 向客户端发送响应内容
        res.end();
      });
      
      server.listen(port, () => {
        console.log('Server is running on http://localhost:' + port);
      });
    }
    module.exports.server = server;
  • router.js文件
    router.js 处理路由逻辑,定义并导出 route 函数,用于在服务器收到请求时处理不同路径

    javascript 复制代码
    function route(pathname, method) {
      console.log("pathname:" + pathname, '请求方式:' + method);
    }
    // 导出了 route 函数
    exports.route = route;
  • index.js文件
    index.js 是程序的入口文件,负责启动服务器并将路由模块传入服务器模块中。
    现在启动应用(node ./index.js,始终记得这个命令行),随后请求一个URL,会看到应用输出相应的信息,表明 HTTP 服务器已经在使用路由模块了,并会将请求的路径传递给路由:

    javascript 复制代码
    var server = require("./server");
    var router = require("./router");
     console.log(router.route)
    server.server(router.route);
相关推荐
冬奇Lab2 小时前
一天一个开源项目(第14篇):CC Workflow Studio - 可视化AI工作流编辑器,让AI自动化更简单
人工智能·开源·编辑器
承渊政道4 小时前
Linux系统学习【Linux基础开发工具】
linux·运维·笔记·学习·centos·编辑器
学嵌入式的小杨同学13 小时前
【Linux 封神之路】信号编程全解析:从信号基础到 MP3 播放器实战(含核心 API 与避坑指南)
java·linux·c语言·开发语言·vscode·vim·ux
Hello World . .18 小时前
Linux:软件编程
linux·运维·服务器·vim
徐小夕@趣谈前端19 小时前
Web文档的“Office时刻“:jitword共建版2.0发布!让浏览器变成本地生产力
前端·数据结构·vue.js·算法·开源·编辑器·es6
毕设源码-朱学姐1 天前
【开题答辩全过程】以 基于Node.js的书籍分享平台设计与实现为例,包含答辩的问题和答案
node.js
zhanglianzhao1 天前
Win 11 WSL 配置Claude code 并在VsCode中使用
ide·vscode·编辑器·claude·cladue code
Keying,,,,1 天前
VScode中终端闪退问题
ide·vscode·编辑器
热爱生活的五柒1 天前
如何在vscode中使用Claude code以及插件中配置setting.json无效的解决方法
ide·vscode·编辑器
前端 贾公子1 天前
Node.js 如何处理 ES6 模块
前端·node.js·es6