从零搭建 Node.js+NextJs企业级 Web 服务器(二):项目基础知识之Express路由模块

Hello World

Express 是一个保持最小规模的灵活的 Node.js Web 应用程序开发框架,为 Web 和移动应用程序提供一组强大的功能。

学习之前我们还是先看一个简单的demo,运行一个hello world程序。

打开终端输入以下命令

bash 复制代码
$ mkdir dockerfile-test
$ cd dockerfile-test
$ yarn init -y
yarn init v1.22.18
warning The yes flag has been set. This will automatically answer yes to all questions, which may have security implications.
success Saved package.json
✨ Done in 0.02s.
$ mkdir src
$ mkdir public
$ cd src
$ touch server.js
$ cd ..
$ cd public
$ touch index.html
$ cd ..
$ yarn add express -S

到目前为止,我们就创建好了一个项目的基础目录,执行 tree -a 可以看到现在的目录如下

bash 复制代码
├── package.json
├── public
│   └── index.html
└── src
    └── server.js

接下来我们来填充下各个文件

html 复制代码
// public/index.html
<html>
    <head>
        <meta charset="utf-8" />
    </head>
    <body>
        <h1>Hello World</h1>
    </body>
</html>

改造src/server.js使用express启动一个服务

js 复制代码
// src/server.js
const express = require('express');
const { resolve } = require('path');
const server = express();
const port = parseInt(process.env.PORT || '8080');
const publicDir = resolve('public');
server.use(express.static(publicDir));
server.listen(port, () => console.log(`Listening on port ${port}`));

改造package.jsonpackage.json 中设置启动脚本:

json 复制代码
// package.json
{
    "name": "dockerfile-test",
    "version": "1.0.0",
    "description": "",
    "main": "index.js",
    "scripts": {
        "start": "node src/server.js",
    },
    "keywords": [],
    "author": "",
    "license": "ISC",
    "dependencies": {
        "express": "^4.18.2"
    },
    "devDependencies": {
        "nodemon": "^3.0.1"
    }
}

启动服务yarn start

bash 复制代码
$ yarn start

不出意外,打开http://localhost:8080,你就能看见以下画面。

是不是很简单呢,没错这就是一个基础的expressweb静态服务。

因为本文只是带大家了解一下一个项目初始阶段的入门知识,所以文本只介绍一些常用的入门模块,后续深入的部分请看我们看正文部分,会带大家手把手的去使用express

下面我们分四个部分去介绍下express。其中 路由 分一个模块讲解、中间件,模板引擎 作为一个模块讲解、错误处理 会在搭建web服务中作为独立模块讲解。

1. 路由

2. 中间件

3. 模板引擎

路由

路由是指确定应用程序如何响应客户端对特定端点的请求,端点是URI(或路径)和特定的HTTP请求方法(GETPOST等)。

每个路由可以有一个或多个处理程序函数,这些函数在路由匹配时执行。

为了能够实时的运行我们编写的程序,这里我们引入一个新的工具nodemonnoodemon是一个用于开发Node.js应用程序的热重载工具。它的主要作用是在开发过程中监视文件的变化,当文件发生更改时,自动重启Node.js应用程序,以便开发人员能够快速地看到代码修改的效果,而无需手动停止和重新启动应用程序。

bash 复制代码
$ yarn add nodemon -S

我们在package.json中配置启动命令

json 复制代码
{
    "name": "dockerfile-test",
    "version": "1.0.0",
    "description": "",
    "main": "index.js",
    "scripts": {
        "start": "node src/server.js",
+        "dev": "nodemon src/server.js"
    },
    "keywords": [],
    "author": "",
    "license": "ISC",
    "dependencies": {
        "express": "^4.18.2"
    },
    "devDependencies": {
        "nodemon": "^3.0.1"
    }
}

Route methods

路线定义格式:

demo 复制代码
server.METHOD(PATH, HANDLER)
  1. serverexpress的一个实例。

  2. METHOD是一个HTTP请求方法,小写

  3. PATH是服务器上的路径。

  4. HANDLER是路由匹配时执行的函数。

示例:

在路由(/home)上响应get请求应用程序:

js 复制代码
server.get('/home', function (req, res) {
    res.send('Hello World!')
})

在路由(/home)上响应POST请求应用程序:

js 复制代码
server.post('/home', function (req, res) {
    res.send('Got a POST request')
})

响应对/user路由的PUT请求:

js 复制代码
server.put('/user', function (req, res) {
    res.send('Got a PUT request at /user')
})

响应对/user路由的DELETE请求:

js 复制代码
server.delete('/user', function (req, res) {
    res.send('Got a DELETE request at /user')
})

有一种特殊的路由方法,server.all()用于在所有HTTP请求方法的路径上加载中间件函数。例如,以下处理程序是为路由"/secret"的请求执行的,无论使用GETPOSTPUTDELETE还是http模块中支持的任何其他HTTP请求方法。

js 复制代码
serve.all('/secret', function (req, res) {
    res.send('Got a request at /secret')
})

将这些代码填充到server.js文件中去。

js 复制代码
// src/server.js
const express = require('express');
const { resolve } = require('path');
const server = express();

+ server.get('/home', function (req, res) {
+     res.send('Hello World!');
+ });

+ server.post('/home', function (req, res) {
+     res.send('Got a POST request');
+ });

+ server.put('/user', function (req, res) {
+     res.send('Got a PUT request at /user');
+ });

+ server.delete('/user', function (req, res) {
+     res.send('Got a DELETE request at /user');
+ });

+ server.all('/secret', function (req, res) {
+     res.send('Got a request at /secret')
+ })

const port = parseInt(process.env.PORT || '8080');
const publicDir = resolve('public');
server.use(express.static(publicDir));
server.listen(port, () => console.log(`Listening on port ${port}`));

使用yarn dev执行命令。打开http://localhost:8080/home。我们能看到Hello World字样,代表你/home路由下的get请求成功了,当然如果你想测试其他请求方法,建议下载一下postman进行测试接口。

例如测试一下user路由下的put方法,我们可以这样。

postman工具的使用因为不是我们的重点,我们这不做过多的介绍。感兴趣的同学可以查看官网。。

Route paths

路由路径与请求方法相结合,定义了可以发出请求的端点。路由路径可以是字符串、字符串模式或正则表达式。Express使用path-to-regexp来匹配路由路径;我们还是来写一些demo来加深大家都路由的理解。

路由路径将匹配acdabcd

js 复制代码
server.get('/ab?cd', function (req, res) {
    res.send('ab?cd')
})

路由路径将匹配abcdabbcdabbbcd

javascript 复制代码
app.get('/ab+cd', function (req, res) {
  res.send('ab+cd')
})

路由路径将匹配abcdabxcdabRANDOMcdab123cd

js 复制代码
server.get('/ab*cd', function (req, res) {
  res.send('ab*cd')
})

......

加入到server.js 使用postman测试一下。下面其他的的大家可以自己去测试。了解了基本的方法建议大家可以学习一下path-to-regexp

Route parameters

路由参数被命名为URL段,用于捕获在URL中的位置指定的值。捕获的值填充在req.params对象中,路径中指定的路由参数的名称作为各自的键。示例格式:

demo 复制代码
Route path: /users/:userId/books/:bookId
Request URL: http://localhost:8080/users/34/books/8989
req.params: { "userId": "34", "bookId": "8989" }

要使用路由参数定义路由,只需在路由路径中指定路由参数,如下所示。

js 复制代码
server.get('/users/:userId/books/:bookId', function (req, res) {
  res.send(req.params)
})

注意:路由参数的名称必须由"单词字符"组成([A-Za-z0-9_]

高级用法 '-''.'

demo 复制代码
Route path: /flights/:from-:to
Request URL: http://localhost:8080/flights/LAX-SFO
req.params: { "from": "LAX", "to": "SFO" }
js 复制代码
server.get('/flights/:from-:to', function (req, res) {
  res.send(req.params)
})
demo 复制代码
Route path: /plantae/:genus.:species
Request URL: http://localhost:3000/plantae/Prunus.persica
req.params: { "genus": "Prunus", "species": "persica" }
js 复制代码
server.get('/plantae/:genus.:species', function (req, res) {
  res.send(req.params)
})
demo 复制代码
Route path: /user/:userId(\d+)
Request URL: http://localhost:3000/user/42
req.params: {"userId": "42"}
js 复制代码
server.get('/user/:userId(\\d+)', function (req, res) {
  res.send(req.params);
});

Route handlers

可以提供多个像中间件一样的回调函数来处理请求。

单个回调函数处理路由。例如:

js 复制代码
server.get('/example/a', function (req, res) {
  res.send('Hello from A!')
})

多个回调函数处理路由(请确保您指定next对象)。例如:

js 复制代码
server.get('/example/b', function (req, res, next) {
  console.log('the response will be sent by the next function ...')
  next()
}, function (req, res) {
  res.send('Hello from B!')
})

响应体会返回Hello from B,控制台会打印the response will be sent by the next function ...

回调函数数组处理路由

js 复制代码
const cb0 = function (req, res, next) {
  console.log('CB0')
  next()
}

const cb1 = function (req, res, next) {
  console.log('CB1')
  next()
}

const cb2 = function (req, res) {
  res.send('Hello from C!')
}

server.get('/example/c', [cb0, cb1, cb2])

响应体会返回Hello from C,控制台会打印CB0CB1 ...

Response methods

以下是 Express 框架中常用于响应对象(res)上的方法,以表格形式列出:

方法 描述
res.send([body]) 发送 HTTP 响应。可以发送字符串、HTMLJSON 对象等不同类型的响应内容。
res.json([body]) 发送 JSON 格式的响应。通常用于发送包含数据的 JSON 响应。
res.render(view, [locals]) 渲染视图模板并发送 HTML 响应。通常与模板引擎一起使用,将数据注入视图模板生成 HTML 页面。
res.redirect([status,] path) 重定向客户端到指定路径。可以指定重定向的状态码,默认为 302(临时重定向)。
res.status(code) 设置 HTTP 响应的状态码。通常用于指定响应状态,如 200(成功)或 404(未找到)。
res.setHeader(name, value) 设置响应头部的字段和值。可以用于自定义响应头部信息。
res.cookie(name, value, [options]) 设置 HTTP 响应中的 cookie。允许在客户端存储数据,通常用于会话管理和用户身份验证。
res.clearCookie(name, [options]) 清除 HTTP 响应中的 cookie。通常用于注销用户或删除存储在客户端的数据。
res.attachment([filename]) 设置响应的 "Content-Disposition" 头部,使得浏览器提示下载文件。
res.set(field, [value]) 设置响应头部的字段和值。类似于 res.setHeader,用于自定义响应头部信息。
res.type(type) 设置响应的 "Content-Type" 头部,指定响应的 MIME 类型。
res.locals 一个包含了响应局部变量的对象。通常用于在中间件中传递数据给视图渲染。
res.sendfile(path, [options], [callback]) 以流的形式发送文件作为响应内容。通常用于提供文件下载或静态文件服务。

这些方法允许你以不同的方式构建和发送 HTTP 响应,根据需要设置状态码、响应头、响应体等内容。 Express 提供了丰富的工具和方法,以便于构建各种类型的 Web 应用程序。

server.route()

您可以使用app.route()为路由路径创建可链接的路由处理程序

js 复制代码
server.route('/book')
  .get(function (req, res) {
    res.send('Get a random book')
  })
  .post(function (req, res) {
    res.send('Add a book')
  })
  .put(function (req, res) {
    res.send('Update the book')
  })

Express Router

Router实例是一个完整的中间件和路由系统,我们结合下一个模块中间件进行讲解。

总结

本文主要是进行了项目的初始搭建和基于express的路由系统讲解,Express.js 的路由模块是构建 Web 应用程序时非常重要的一部分。它负责将客户端请求映射到相应的处理程序函数,从而实现不同 URL 路径的不同行为。

一个来自底层的小白程序员,希望大家多多点赞收藏关注,你的鼓励是我前进的动力,谢谢大家。

完整代码

github地址

参考资料

相关推荐
前端小盆友2 小时前
从零实现一个GPT 【React + Express】--- 【4】实现文生图的功能
react.js·chatgpt·express
实习生小黄3 小时前
express 连接在线数据库踩坑
node.js·express
Thomas游戏开发5 小时前
Unity3D Boehm GC原理解析
前端框架·unity3d·游戏开发
Thomas游戏开发5 小时前
Unity3D 文件夹注释工具
前端框架·unity3d·游戏开发
liangshanbo12156 小时前
微前端框架对比
前端框架
NetX行者6 小时前
基于Vue 3的AI前端框架汇总及工具对比表
前端·vue.js·人工智能·前端框架·开源
伍哥的传说7 小时前
H3初识——入门介绍之常用中间件
前端·javascript·react.js·中间件·前端框架·node.js·ecmascript
遂心_8 小时前
深入剖析React待办事项应用:Hooks、组件化与性能优化实战
前端·react.js·前端框架
摸鱼仙人~18 小时前
styled-components:现代React样式解决方案
前端·react.js·前端框架
Baklib梅梅20 小时前
Ruby大会演讲实录:Baklib 如何用 AI 重构内容管理赛道
ruby on rails·前端框架·ruby