Express
Express简介
Express 是一个简洁而灵活的 node.js Web应用框架, 提供了一系列强大特性帮助你创建各种 Web 应用,和丰富的 HTTP 工具。
使用 Express 可以快速地搭建一个完整功能的网站。
Express 框架核心特性:
- 实现路由的功能–路由分发,在使用express框架之前,需要使用大量的判断实现路由分发的功能
- 中间件的功能,将需要写在服务中的方法和程序进行封装
- 对req和res对象进行了扩展
- 可以继承其他模板的引擎
Express基础知识
1.创建方式
(1)导入express模块
var express=require('express');
(2) 调用方法,返回app
var app=express();
(3)端口监听 最后执行
app.listen(3000);//异步
整体代码:
const express = require('express')
const app = express()
app.listen(8080, () => {
console.log('port created successfully')
})
2.定义方式
根据不同的客户端请求,返回不同的响应
3.app上的方法(app本质:请求监听函数)
(1)注册路由的方法
// 请求方法必须是get,请求路径的 pathname 必须严格等于(===)/index
app.get('/index', (req, res) => {
res.send('get请求 /index');
});
// 请求方法必须是post,请求路径的 pathname 必须严格等于(===)/add
app.post('/add', (req, res) => {
res.send('post请求 /add');
});
// 请求方法必须是put,请求路径的 pathname 必须严格等于(===)/user
app.put('/user', (req, res) => {
res.send('put请求 /user');
});
// 请求方法必须是delete,请求路径的 pathname 必须严格等于(===)/user
app.delete('/user', (req, res) => {
res.send('delete请求 /user');
});
(2)app.use()注册路由
// 1、在进行路由匹配的时候,不限定方法,什么请求方法都可以
// 2、请求路径的第一部分等于 /index 相等即可,并不要求请求路径的 pathname 严格等于(===)/index
// 匹配/index/sgjtf/fhr等,不匹配/indexdghbv
app.use('/index', (req,res) => {
res.send('index');
});
// app.use()第一个参数不传,默认为'/'
app.use('/', (req, res) => {
res.send('hello');
});
// 等价于
app.use((req, res) => {
res.send('hello');
});
(3)app.all() 注册路由
// 1、在进行路由匹配的时候,不限定方法,什么请求方法都可以
// 2、请求路径的 pathname 必须严格等于(===)/index
app.all('/index', (req,res) => {
res.send('index');
});
(4)通过正则表达式注册路由
// 1、请求方法必须是get
// 2、请求路径的第一部分等于 /index 相等即可,并不要求请求路径的 pathname 严格等于(===)/index
// 匹配/index/sddf/srrd等,不匹配/indexsdfgg
app.get(/^\/index(\/.+)*$/, (req,res) => {
res.send('index');
});
注意:app.route()
可使用 app.route() 创建路由路径的链式路由句柄。由于路径在一个地方指定,这样做有助于创建模块化的路由,而且减少了代码冗余和拼写错误。
app.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');
});
4.详细信息的获取
原理:
var urlObj=require(‘url’).parse(req.url,true);
req.path=urlObj.path;
req.query=urlObj.query;
- req.method 请求方法
- req.url 请求URL
- req.path 请求路径// pathname /food
- req.header 请求头对象
- req.query 获取查询字符串
- req.params 获取请求URL中的参数值
app.get('/user/:username/:id', (req, res) => {
res.send(req.params);
});
5.res对象的常用方法
(1)res.json()
app.get('/', (req, res) => {
// res.json()发送一个json响应,效果跟 res.send() 发送一个json响应一样
res.json({name: 'liu', age:18});
});
res.json()默认发送的响应报文头
(2)res.redirect()
app.get('/', (req, res) => {
// res.direct() 重定向,第一个参数为状态码,不设置默认为302
res.redirect('https://www.baidu.com');
});
响应完成后直接跳转到https://www.baidu.com
// 设置状态码,不用设置状态码对应的状态消息,默认有对应的状态消息
res.redirect(301, 'https://www.baidu.com');
(3)res.sendFile()
app.get('/', (req, res) => {
// res.sendFile() 读取文件作为响应数据
// 会根据文件的扩展名,设置响应头中的 Content-Type类型
res.sendFile(path.join(__dirname, 'public', 'detail.html'), err => {
if (err) throw err;
console.log('ok');
});
});
6.中间件
中间件就是处理HTTP请求的函数。它的特点就是,一个中间件处理完,再传递给下一个中间件。
每个中间件都可以接收三个参数,依次为request对象(代表HTTP请求)、response对象(代表HTTP回应),next回调函数(代表下一个中间件)。每个中间件都可以对HTTP请求(request对象)进行加工,并且决定是否调用next方法,将request对象再传给下一个中间件。
(1)使用
var express=require('express');
var app=express();
app.use((req,res)=>{});
app.listen(3200);
(2)参数
- 参数1:req
- 参数2:res
- 参数3:next 函数 调用表示继续向下执行
(3)特点
- 按顺序执行;
- 可执行任何脚本;
- 可以对request对象和response对象进行overwrite;
- 可以响应请求以结束本次请求生命周期;
- 通过next方法执行下一个中间件;
解决方式
通过setTimeOut(function(){
next() //等异步执行完执行next()
})
(4)作用
- 添加公共处理器
- 给请求或响应对象上增加公有的方法和属性 req.path
7.路由中间件
- 根据不同请求实现不同的功能
- 根据不同的路径请求开头分别交由各自所属范围进行执行
- 引用 创建 执行 发送
user.js
var express=require('express');
var router=express.Router();
router.get('/signup',function(req,res){})
module.exports=router
路由中间件部分
var express=require('express');
var app=express();
var user=require('./router/user');
var article=require('./router/article');
/*用户 /user/sginup */
/*当请求的URL路径是以user开头的话,会交由 */
app.use('/user',user);
app.use('/article',article);
app.listen(7979);
8.Express 托管静态文件
Express 内置的 express.static 可以方便地托管静态文件,例如图片、CSS、JavaScript 文件等。
将静态资源文件所在的目录作为参数传递给 express.static 中间件就可以提供静态资源文件的访问
- 参数 :静态文件根目录
- 查找执行方式
(1)在根目录下查找,找到则返回
直接从public文件之下开始查找,会返回一个函数
方式一: app.use(express.static(path.join(__dirname,'public')));
方式二:(1)app.use(express.static(path.resolve('public'))); //-》不写/user,是全部都可以
(2)app.use('/user',express.static(path.resolve('public'))); //-》只有满足/user前缀才可以匹配
(2)根目录下找不到 next向下执行
代码原理:
function static(root) {
//返回一个中间件函数
return function (req, res, next) {
//静态文件根目录+客户端请求路径
var filename=path.join(root,req.path);
fs.exists(filename,function (exist) {
if(exist){
res.sendFile(filename);//发送文件给客户端
}else{
next();
}
})
}
}
9.body-parser中间件
- 用于解析客户端请求的body中的内容
- 获取请求体字符串转化城对象赋给req.body
app.use(bodyParser.urlencoded({extended:true}));
10.处理404
Express 对于没有设定的请求路径,默认会返回 Cat not get xxx, 如果想要定制这个 404,需要通过中间件来配置
app.use((req,res)=>{
res.send("错误")
})
11.res.send() 和 res.end() 的区别
(1)参数类型区别:
- res.send() 参数类型可以是一个 Buffer 对象、字符串、对象、数组
- res.end() 参数类型只能是 Buffer 对象 或是 字符串
(2)默认自动发送的响应报文头不同
- res.end()默认发送的响应报文头
- res.send()默认发送的响应报文头
从上面可以看出:res.send()默认的响应报文头,设置了 Content-Type: text/html; charset=utf-8,所以中文不乱码
(3)res.send()默认的响应报文头的Content-Type类型,根据响应的数据来确定
res.send('<h1>123</h1>');
或是
res.send('hello');
res.send()默认发送的响应报文头为:
res.send({name: 'liu', age:18});
res.send()默认发送的响应报文头为: