express框架
Express 框架核心特性:
- 可以设置中间件来响应 HTTP 请求。
- 定义了路由表用于执行不同的 HTTP 请求动作。
- 可以通过向模板传递参数来动态渲染 HTML 页面。
1-Express的基本使用(重点)
安装
npm install express -S;// 先下载安装express框架
使用 (搭建一个最基本的web服务器)
// 1. 引入框架模块
const express = require('express')
// 2. 创建服务器--创建一个应用
const app = express();
// 3. 开启服务器并监听端口
app.listen(3000,()=>{
console.log('express server is running at http://127.0.0.1:3000');
})
// 4.调用Express中内置【中间件】来监听用户的请求响应
// server.get(url,处理函数)
//server.get('/list', (req, res) => {
// console.log('aaa')
//})
// use是一个中间件,可以用来监听get和post请求
app.use((req,res)=>{
// res.end('express框架的基本使用...');// 直接返回带有中文的内容会有乱码 加响应头后可以解决
res.send('express框架的基本使用...') ;// 可以直接返回中文并解析不会出现乱码
})
2-中间件
基本概念
中间件就是一个处理函数,用来监听用户的请求响应
从本质上来说,一个Express应用就是在调用各种中间件.
中间件的常见功能包括:
- 执行任何代码。
- 修改请求和响应对象。
- 终结请求-响应循环。
- 调用堆栈中的下一个中间件。
- …
应用级中间件
应用级中间件绑定到app对象,使用app.use()和app.method(),其中,METHOD是需要处理的HTTP请求的方法,例如GET,POST,PUT等,全部小写.例如:
const app = express()
// 没有挂载路径的中间件,应用的每个请求都会执行该中间件
app.use((req,res,next)=>{
console.log('Time:',Date.now());
next();
})
// 挂载至 /user/:id的中间件,任何指向/user/:id的请求都会执行它
app.use('/user/:id',(req,res,next)=>{
console.log('Request Type',req.method);
next()
})
// 路由和句柄函数(中间件系统),处理指向/user/:id的GET请求
app.get('/user/:id',(req,res,next)=>{
res.rend('USER')
})
路由级中间件
路由级中间件和应用级中间件一样,只是它绑定的对象为express.Router()
const router = express.Router()
路由级使用router.use()或router.verb()加载。
上述在应用级创建的中间件系统,可通过如下代码改写为路由级:
const app = express()
const router = express.Router()
// 没有挂载路径的中间件,通过该路由的每个请求都会执行该中间件
router.use((req,res,next)=>{
console.log('Time:',Date.now());
next();
})
// 一个中间件栈,显示任何指向/user/:id的HTTP请求的信息
router.use('/user/:id',(req,res,next)=>{
console.log('Request URL:',req.originalUrl);
next();
},(req,res,next)=>{
console.log('Request Type',req.method);
next();
})
错误处理中间件
所有错误都会经过这个中间件
错误处理中间件有4个参数,定义错误处理中间件时必须使用这4个参数。即使不需要next对象,也必须在签名中声明它,否则中间件会被识别为一个常规中间件,不能处理错误。
错误处理中间件和其他中间件定义类似,只是要使用4个参数,而不是3个,其签名如下:(err,req,res,next)
app.use((err,req,res,next)=>{
console.error(err.stack);
res.status(500).send('404')
})
内置中间件
从4.x版本开始,除了express.static,Express以前内置的中间件现在已经全部单独作为模块安装使用了.
express.static(root,[options])
express.static是Express唯一内置的中间件。它基于server-static,负责在Express应用中托管静态资源。
第三方中间件
通过使用第三方中间件从而为Express应用增加更加功能
安装所需要功能的node模块,并在应用中加载,可以在应用级加载,也可以在路由级加载。
body-parser:接收post方式所传递的参数,解析
//下包
npm install body-parser
//引入第三方中间件
const bodyParser = require('body-parser')
// 添加body-parse解析器
// 这个模块的作用是接收post方式所传递的普通键值对(不能用于上传文件)
var bodyParser = require('body-parser')
.............................................
// 添加body-parse解析器,以后有参数,就挂载到req.body属性上
app.use(bodyParser.json()) // 可以接收post方式所传递的json格式字符串
app.use(bodyParser.urlencoded({ extended: false })) // 接收带编码格式的字符串(application/x-www-form-urlencoded)
3-接收get和post的不同请求(了解)
每一个路由都可以有一个或者多个处理器函数,当匹配到路由时,这(个/些)函数将被执行。
路由的定义由如下结构组成:app.method(routerPath,handler)
其中,app是一个express实例;method是某个HTTP请求方式中的一个;routerPath是服务器端的路径;handler是当路由匹配到时需要执行的函数。
// 1. 引入框架模块
var express = require('express')
// 2. 创建服务器
var app = express();
// 3. 开启服务器并监听端口
app.listen(3000,()=>{
console.log('express server is running at http://127.0.0.1:3000');
})
// 4.给app对象注册中间件,监听请求
app.get('/',(req,res,next)=>{
res.send('这是一个index的主页面...')
})
app.get('/movie', (req, res) => {
res.send('这是一个电影的主页面...')
})
app.post('/login', (req, res) => {
res.send('这是一个登陆的主页面...')
})
4-express.static托管静态资源(重点)
4.1 响应静态资源
将静态资源文件(图片、CSS、JavaScript文件等)所在的目录作为参数传递给express.static中间件就可以提供静态资源文件的访问了.
为express.static功能所服务的文件创建虚拟路径,查找时会忽略掉这个
app.use('/css', express.static('css'))
app.use('/js', express.static('js'))
app.use('/images', express.static('images'))
一次托管多个静态资源文件
//在public目录放置了图片、CSS和JavaScript文件
app.use(express.static('public'));
4.2 响应页面资源
中间件可以实现当前服务器内部的静态页面的相互访问,我们只需要将前端页面或资源放到服务器的某个目录下,并配置静态资源访问。
需要将当前网站的页面资源放置到views目录中
// use:代表所有请求都会经过
// '/':只有发起向/的请求才会进行处理
// express.static:这个中间件函数就可以实现静态页面的自动访问,它会默认打开views下面的index.html
app.use('/', express.static(path.join(__dirname, 'views')))
5-express.Router创建路由(重点)
可使用express.Router类创建模块化、可挂载的路由句柄。Router实例是一个完整的中间件和路由系统,因此常称其为一个"mini-app"。
路由的主要功能是进行请求的处理分发,就是确定用户的请求到底应该由那个模块进行处理,所以它一般就是调用模块的方法进行业务的处理
创建路由
// 引入express
const express = require('express')
const handler = require('./handler')
// 创建路由对象
const router = express.Router()
// 添加(挂载)路由配置
router.post('/register', (req, res) => {
handler.userRegister(req, res)
})
// 暴露
module.exports = router
6-使用express实现用户注册案例
app.js页面
//引入第三方模块
//引入Express框架模块
const express = require('express')
const path = require('path')
//引入自定义模块需要使用相对路径
//引入路由模块
const router = require('./router')
const app = express()
app.listen('4000', () => {
console.log('http://127.0.0.1:4000');
})
// 以前约定了三个:响应注册页面,静态资源 ,注册功能
// 响应页面资源
// use:代表所有请求都会经过
// '/':只有发起向/的请求才会进行处理
// express.static:这个中间件函数就可以实现静态页面的自动访问,它会默认打开views下面的index.html
app.use('/', express.static(path.join(__dirname, 'views'))))
// 找到public里面的所有资源
app.use(express.static('public'))
// 明确安装路由功能:让当前应用使用router模块进行路由的管理
app.use(router)
router.js页面
//引入Express框架模块
const express = require('express')
// 引入业务处理操作页
const handler = require('./handler')
// 创建一个路由模块
const router = express.Router()
// 添加(挂载)路由配置
router.post('/register', function (req, res) {
// 接收post请求方式的参数
handler.userRegister(req, res)
})
// 暴露
module.exports = router
handle.js页面
const bodyParser = require('body-parser')
const fs = require('fs')
const path = require('path')
// 进行业务处理
module.exports = {
userRegister: function (req, res) {
// express封装了get请求参数的接收
// req.query 是express自带的
// 接收用户参数 以前req.on('data') req.on('end') > 参数的类型转换
// body:就是post方式所传递的参数,它是一个对象(参数的接收和参数的转换)
// console.log(req.body)
// 存储到指定的数据文件中,并响应结果
fs.readFile(path.join(__dirname, '/data/users.json'), 'utf-8', (err, data) => {
if (err) {
console.log(err)
// json:转换 + 响应
res.json({ code: 204, msg: '注册失败' })
} else {
let arr = JSON.parse(data)
arr.push(req.body)
fs.writeFile(path.join(__dirname, '/data/users.json'), JSON.stringify(arr, null, ' '), (err) => {
if (err) {
console.log(err)
// json:转换 + 响应
res.json({ code: 204, msg: '注册失败' })
} else {
res.json({ code: 200, msg: '注册成功' })
}
})
}
})
}
}