1.1 Express 简介
官网给出的概念:Express 是基于 Node.js 平台,疾速、凋谢、极简的 Web 开发框架。艰深的了解:Express 的作用和 Node.js 内置的 http 模块相似,是专门用来创立 Web 服务器的。Express 的实质: 就是一个 npm 上的第三方包,提供了疾速创立 Web 服务器的便捷办法。
Express 的中武官网: http://www.expressjs.com.cn/
1.2 Express 的根本应用
1. 装置
在我的项目所处的目录中,运行如下的终端命令,即可将 express 装置到我的项目中应用:
npm i express@4.17.1
2. 创立根本的 Web 服务器
监听 GET ** 申请
** 通过 app.get() 办法,能够监听客户端的 GET 申请,具体的语法格局如下
// 参数 1:客户端申请的 URL 地址
// 参数 2:申请对应的处理函数
// req: 申请对象(蕴含了与申请相干的属性与办法)// res: 响应对象(蕴含了与申请相干的属性与办法)app.get("申请 url",function(req,res)){/* 处理函数 */}
监听 POST ** 申请
** 通过 app.post() 办法,能够监听客户端的 POST 申请,具体的语法格局如下
// 参数 1:客户端申请的 URL 地址
// 参数 2:申请对应的处理函数
// req: 申请对象(蕴含了与申请相干的属性与办法)// res: 响应对象(蕴含了与申请相干的属性与办法)app.post("申请 url",function(req,res)){/* 处理函数 */}
获取 URL ** 中携带的查问参数
** 通过 req.query 对象,能够拜访到客户端通过查问字符串的模式,发送到服务器的参数
获取 URL 中的** 动静参数
通过 req.params 对象,能够拜访到 URL 中,通过 :** 匹配到的动静参数:
// 1. 导入 express
const express = require('express')
// 2. 创立 web 服务器
const app = express()
// 4. 监听客户端的 GET 和 POST 申请,并向客户端响应具体的内容
app.get('/user', (req, res) => {// 调用 express 提供的 res.send() 办法,向客户端响应一个 JSON 对象
res.send({name: 'zs', age: 20, gender: '男'})
})
app.post('/user', (req, res) => {// 调用 express 提供的 res.send() 办法,向客户端响应一个 文本字符串
res.send('申请胜利')
})
app.get('/', (req, res) => {
// 通过 req.query 能够获取到客户端发送过去的 查问参数
// 留神:默认状况下,req.query 是一个空对象
console.log(req.query)
res.send(req.query)
})
// 留神:这里的 :id 是一个动静的参数
app.get('/user/:ids/:username', (req, res) => {
// req.params 是动静匹配到的 URL 参数,默认也是一个空对象
console.log(req.params)
res.send(req.params)
})
// 3. 启动 web 服务器
app.listen(80, () => {console.log('express server running at http://127.0.0.1')
})
托管动态资源
1**. express.static()
** express 提供了一个十分好用的函数,叫做 express.static(),通过它,咱们能够十分不便地创立一个动态资源服务器,
例如,通过如下代码就能够将 public 目录下的图片、CSS 文件、JavaScript 文件对外开放拜访了
app.use(express.static('public'))
当初,你就能够拜访 public 目录中的所有文件了:
http://localhost:3000/images/bg.jpg
http://localhost:3000/css/style.css
http://localhost:3000/js/login.js
留神:Express 在指定的动态目录中查找文件,并对外提供资源的拜访门路。
因而,寄存动态文件的目录名不会呈现在 url 中。
托管多个动态资源目录 如果要托管多个动态资源目录,请屡次调用 express.static() 函数:
app.use(express.static('public'))
app.use(express.static('files'))
拜访动态资源文件时,express.static() 函数会依据目录的增加程序查找所需的文件。
挂载 门路前缀 如果心愿在托管的动态资源拜访门路之前,挂载门路前缀,则能够应用如下的形式
app.use('public',express.static('public'))
当初,你就能够通过带有 /public 前缀地址来拜访 public 目录中的文件了:
http://localhost:3000/public/images/kitten.jpg
http://localhost:3000/public/css/style.css
http://localhost:3000/public/js/app.js
nodemon
在编写调试 Node.js 我的项目的时候,如果批改了我的项目的代码,则须要频繁的手动 close 掉,而后再重新启动,十分繁琐。
当初,咱们能够应用 nodemon(https://www.npmjs.com/package… 这个工具,它可能监听我的项目文件 的变动,当代码被批改后,nodemon 会主动帮咱们重启我的项目,极大不便了开发和调试。
装置 nodemon
在终端中,运行如下命令,即可将 nodemon 装置为全局可用的工具:
npm install -g nodemon
当基于 Node.js 编写了一个网站利用的时候,传统的形式,是运行 node app.js 命令,来启动我的项目。这样做的害处是: 代码被批改之后,须要手动重启我的项目。
当初,咱们能够将 node 命令替换为 nodemon 命令,应用 nodemon app.js 来启动我的项目。这样做的益处是: 代码 被批改之后,会被 nodemon 监听到,从而实现主动重启我的项目的成果。
node app.js
将下面的终端命令,替换为上面的终端命令,即可实现主动重启我的项目的成果
nodemon app.js
路由的概念
在 Express 中,路由指的是客户端的申请与服务器处理函数之间的映射关系。
Express 中的路由分 3 局部组成,别离是申请的类型、申请的 URL 地址、处理函数.
路由的简略用法:
const express = require('express')
const app = express()
// 挂载路由
app.get('/', (req, res) => {res.send('hello world.')
})
// 挂载路由
app.post('/', (req, res) => {res.send('Post Request.')
})
app.listen(80, () => {console.log('http://127.0.0.1')
})
模块化路由
为了不便对路由进行模块化的治理,Express 不倡议 将路由间接挂载到 app 上,而是举荐将路由抽离为独自的模块。将路由抽离为独自模块的步骤如下:
1 创立路由模块对应的 .js 文件
2 调用 express.Router() 函数创立路由对象
3 向路由对象上挂载具体的路由
4 应用 module.exports 向外共享路由对象
5 应用 app.use() 函数注册路由模块
03.router
// 这是路由模块
// 1. 导入 express
const express = require('express')
// 2. 创立路由对象
const router = express.Router()
// 3. 挂载具体的路由
router.get('/user/list', (req, res) => {res.send('Get user list.')
})
router.post('/user/add', (req, res) => {res.send('Add new user.')
})
// 4. 向外导出路由对象
module.exports = router
调用自定义模块化的路由
const express = require('express')
const app = express()
// app.use('/files', express.static('./files'))
// 1. 导入路由模块
const router = require('./03.router')
// 2. 注册路由模块,并给路由模块增加前缀
app.use('/api', router)
// 留神:app.use() 函数的作用,就是来注册全局中间件
app.listen(80, () => {console.log('http://127.0.0.1')
})
中间件
中间件(Middleware),特指业务流程的两头解决环节。
全局失效 的中间件
客户端发动的任何申请,达到服务器之后,都会触发的中间件,叫做全局失效的中间件。通过调用 app.use(中间件函数),即可定义一个全局失效的中间件,示例代码如下:
// 定义一个最简略的中间件函数
const mw = function (req, res, next) {console.log('这是最简略的中间件函数')
// 把流转关系,转交给下一个中间件或路由
next()}
// 将 mw 注册为全局失效的中间件
app.use(mw)
定义全局中间件的简化模式
// 这是定义全局中间件的简化模式
app.use((req, res, next) => {
// 获取到申请达到服务器的工夫
const time = Date.now()
// 为 req 对象,挂载自定义属性,从而把工夫共享给前面的所有路由
req.startTime = time
next()})
定义多个全局中间件:
const express = require('express')
const app = express()
// 定义第一个全局中间件
app.use((req, res, next) => {console.log('调用了第 1 个全局中间件')
next()})
// 定义第二个全局中间件
app.use((req, res, next) => {console.log('调用了第 2 个全局中间件')
next()})
// 定义一个路由
app.get('/user', (req, res) => {res.send('User page.')
})
app.listen(80, () => {console.log('http://127.0.0.1')
})
部分失效的中间件:
// 导入 express 模块
const express = require('express')
// 创立 express 的服务器实例
const app = express()
// 1. 定义中间件函数
const mw1 = (req, res, next) => {console.log('调用了部分失效的中间件')
next()}
// 2. 创立路由
app.get('/', mw1, (req, res) => {res.send('Home page.')
})
app.get('/user', (req, res) => {res.send('User page.')
})
// 调用 app.listen 办法,指定端口号并启动 web 服务器
app.listen(80, function () {console.log('Express server running at http://127.0.0.1')
})
定义多个部分中间件:
能够在路由中,通过如下两种等价的形式,应用多个部分中间件:
// 一下两种写法是齐全等价的。app.get('/', mw1, mw2, (req, res) => {res.send('Home page.')})
app.get('/', [mw1, mw2], (req, res) => {res.send('Home page.')})
理解中间件的 5 个应用注意事项
1 肯定要在路由之前注册中间件
2 客户端发送过去的申请,能够间断调用多个中间件进行解决
3 执行完中间件的业务代码之后,不要遗记调用 next() 函数
4 为了避免代码逻辑凌乱,调用 next() 函数后不要再写额定的代码 5 间断调用多个中间件时,多个中间件之间,共享 req 和 res 对象
中间件的分类
为了不便大家了解和记忆中间件的应用,Express 官网把常见的中间件用法,分成了 5 大类,别离是:
1 利用级别的中间件
2 路由级别的中间件
3 谬误级别的中间件
4 Express 内置的中间件
5 第三方的中间件
利用级别的中间件
通过 app.use() 或 app.get() 或 app.post(),绑定到 app 实例上的中间件,叫做利用级别的中间件,代码示例如下:
// 利用级别的中间件(全局中间件)app.use((req,res,next)=>{next()
})
// 利用级别的中间件,(部分中间件)app.get('/',mw1,(req,res)=>{res.send("Hello world")
})
路由级别的中间件
绑定到 express.Router() 实例上的中间件,叫做路由级别的中间件。它的用法和利用级别中间件没有任何区别。只不 过,利用级别中间件是绑定到 app 实例上,路由级别中间件绑定到 router 实例上,代码示例如下:
const app = express()
var router = express.Router()
// 路由级别的中间件
router.use(function(req,res,next){console.log("time",Date.now())
next()})
app.use('/',router)
谬误级别的中间件 谬误级别中间件作用: 专门用来捕捉整个我的项目中产生的异样谬误,从而避免我的项目异样解体的问题。
格局: 谬误级别中间件的 function 处理函数中,必须有 4 个形参,形参程序从前到后,别离是 (err, req, res, next)。
留神: 谬误级别的中间件,必须注册在所有路由之后!
// 导入 express 模块
const express = require('express')
// 创立 express 的服务器实例
const app = express()
// 1. 定义路由
app.get('/', (req, res) => {
// 1.1 人为的制作谬误
throw new Error('服务器外部产生了谬误!')
res.send('Home page.')
})
// 2. 定义谬误级别的中间件,捕捉整个我的项目的异样谬误,从而避免程序的解体
app.use((err, req, res, next) => {console.log('产生了谬误!' + err.message)
res.send('Error:' + err.message)
})
// 调用 app.listen 办法,指定端口号并启动 web 服务器
app.listen(80, function () {console.log('Express server running at http://127.0.0.1')
})
Express 内置的中间件
自 Express 4.16.0 版本开始,Express 内置了 3 个罕用的中间件,极大的进步了 Express 我的项目的开发效率和体验:
1 express.static 疾速托管动态资源的内置中间件,例如: HTML 文件、图片、CSS 款式等(无兼容性)
2 express.json 解析 JSON 格局的申请体数据(有兼容性,仅在 4.16.0+ 版本中可用)
3 express.urlencoded 解析 URL-encoded 格局的申请体数据(有兼容性,仅在 4.16.0+ 版本中可用)
// 配置解析 application/json 格局数据的内置中间件
app.use(express.json())
// 配置解析 application/x-www-form-urlencoded 格局数据的内置中间件
app.use(express.urlencodeed({extended:false}))
获取申请体中的 json 数据
// 导入 express 模块
const express = require('express')
// 创立 express 的服务器实例
const app = express()
// 留神:除了谬误级别的中间件,其余的中间件,必须在路由之前进行配置
// 通过 express.json() 这个中间件,解析表单中的 JSON 格局的数据
app.use(express.json())
// 通过 express.urlencoded() 这个中间件,来解析 表单中的 url-encoded 格局的数据
app.use(express.urlencoded({ extended: false}))
app.post('/user', (req, res) => {
// 在服务器,能够应用 req.body 这个属性,来接管客户端发送过去的申请体数据
// 默认状况下,如果不配置解析表单数据的中间件,则 req.body 默认等于 undefined
console.log(req.body)
res.send('ok')
})
app.post('/book', (req, res) => {
// 在服务器端,能够通过 req,body 来获取 JSON 格局的表单数据和 url-encoded 格局的数据
console.log(req.body)
res.send('ok')
})
// 调用 app.listen 办法,指定端口号并启动 web 服务器
app.listen(80, function () {console.log('Express server running at http://127.0.0.1')
})
非 Express 官网内置的,而是由第三方开发进去的中间件,叫做第三方中间件。在我的项目中,大家能够按需下载并配置
第三方中间件,从而进步我的项目的开发效率。
例如: 在 express@4.16.0 之前的版本中,常常应用 body-parser 这个第三方中间件,来解析申请体数据。应用步 骤如下:
1 运行 npm install body-parser 装置中间件
2 应用 require 导入中间件
3 调用 app.use() 注册并应用中间件
留神:Express 内置的 express.urlencoded 中间件,就是基于 body-parser 这个第三方中间件进一步封装进去的