Express 简介
什么是Express
express是一个基于node.js的极简、灵活的web开发框架。可以实现非常强大的web服务器功能。
Express的特点
- 可以设置中间件响应或过滤http请求。
- 可以使用路由实现动态网页,响应不同的http请求。
- 内置支持ejs模板(默认是jade模板)实现模板渲染生成html。
express-generator生成器
express-generator是express官方团队为开发者准备的一个快速生成工具,可以非常快速的生成一个基本的express开发框架。
express的安装使用
安装express-generator生成器
cnpm install express -gd
cnpm i -g express-generator //安装 完成后可以使用express命令,需要安装淘宝镜像
npm i -g express-generator//直接安装,较慢
ln -s /opt/node-v8.11.1-linux-x64/bin/express /usr/sbin/express
ln -s /opt/node-v8.11.1-linux-x64/bin/express /usr/bin/express
express --version
forever守护nodejs进程 (一直在线访问)
客户端可以正常启动应用,但是如果断开客户端连接,应用也就随之停止了。也就是说这样的启动方式没有给应用一个守护线程
Forever可以解决这个问题!Forever可以守护Node.js应用,客户端断开的情况下,应用也能正常工作
安装forever
cd app cnpm install forever -g ln -s /opt/node-v8.11.1-linux-x64/bin/forever /usr/sbin/forever ln -s /opt/node-v8.11.1-linux-x64/bin/forever /usr/bin/forever
forever启动进程
cd bin forever start www
注意:可能需要以管理员身份运行cmd
创建项目
express xxx 项目名称//自动创建项目目录
安装依赖
cnpm install
cnpm i//简写
npm install
npm i//简写
开启项目
node app
npm start//自动查找当前目录下的package.json文件
node ./bin/www
node app
需要手动添加监听端口,打开app.js添加以下内容:
app.listen(3000,function(){
console.log("服务器已运行");
});
监听端口为:80
npm start
:默认监听端口为:3000
测试项目
打开浏览器输入localhost
或127.0.0.1
目录说明
- bin 可执行文件目录
- node_moudles 依赖包的目录
- public 静态文件根目录
- 所有的静态文件都应该放在这个目录的下面(静态html,css,js,图片,字体,视频资源等)
- routes 路由模块目录,动态文件的目录
- 优先找静态文件,如果没有静态存在则找动态路由,如果动态路由也没有就404
- views 视图目录
- 用于存储所有的ejs模板
文件说明
- app.js 项目的主文件
- 对整个项目的所有的字眼进行统筹的安排
var indexRouter = require('./routes/index');//引入处理根目录请求的路由
var usersRouter = require('./routes/users');//引进处理users目录请求的路由
app.use('/', indexRouter);//分配根目录下的请求给index去处理
app.use('/users', usersRouter);//分配users目录下的请求给users模块去处理
app.set('views', path.join(__dirname, 'views'));//设置模板的默认目录
app.set('view engine', 'ejs');//设置模板引擎为ejs模板
app.use(express.static(path.join(__dirname, 'public')));//设置静态文件目录
- package.json 项目描述文件
- 生命项目的名称、版本、依赖包等信息
路由
什么是路由
路由是指接收用户请求,处理用户数据,返回结果给用户的一套程序。可以理解为:生成动态网页的程序。
后端路由的核心: URL
express对象自带有一个Router类,可以实例化出路由对象,可以在该对象上挂载非常多的路由节点。
路由的写法
挂载路由线路的写法:
router.请求方式('请求地址',function(req,res){
res.send('数据');
});
创建一个独立的路由模块
需求:创建一个vip路由模块,接收vip目录下的所有请求,响应数据。
实现步骤:
创建一个vip路由模块
编写路由模块的代码(在Router文件夹下新建vip.js)
a. 引入express模块
b. 实例化路由对象
c. 编写路由线路挂载到路由对象上
d. 暴露路由对象
代码:
var express = require('express');//引入express模块
var router = express.Router();//利用Router类创建一个路由的实例
//编写list.html用于展示所有的vip用户
router.get('/list.html', function(req, res, next){
res.send('<h1>张三,李四,王五</h1>');
});
router.get('/info.html', function(req, res, next){
res.send('<h1>张三:23,李四:23,王五:24</h1>');
});
module.exports = router;
注意:写请求路径news.html时不需要添加父路径/vip
- 将编写好的路由模块引入到主模块中,由主模块分配对应的请求到该模块中去处理(主模块为app.js)
代码
var appRouter = require('./routes/vip');//引入vip模块
app.use('/vip',appRouter);//分配vip目录下的请求给vip路由模块去处理
路由的区分
大路由(总路由) : app.js负责接收所有请求,对请求进行分配
小路由(分路由) : /routes下面的所有路由模块,只负责处理自己能管理的目录下的所有请求
响应对象
什么是响应对象
响应对象(res)是指服务器向容户端响应数据的对象,包含了所有要响应的内容
响应对象的方法
res.send() //返回任意类型的数据
例:
router.get('/',function(req,res){
//res.send('hello world'); //可以返回字符串数据
//var data={"name":"李白", "age":999};
//res.send(data); // 也可以返回一个JSON数据
//res.send(1);//返回数字,即状态码
//res.send('1');//返回数字1
//返回状态码+数据链式调用
// res.status(404).send("页面不见啦。。。。");
});
注意:
- 如果返回一个数字,就会被当成状态码,容易报错。
- send方法能且仅能出现一次,重复无效且会报错,不写的话会挂起
res.json();
返回JSON数据,自动设置相应头
和send方法传递JSON数据的区别不大
例
router.get('/',function(req,res){
//var data={"name":"李白", "age":999};
//res.json(data); // 返回json自动设置响应头
});
自己新建模板文件list.ejs
代码
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>用户列表</title>
</head>
<body>
<ul>
<%for(var i in users){%>
<li>姓名:<%=users[i].name%>====年龄:<%=users[i].age%></li>
<%}%>
</ul>
</body>
</html>
res.render(“模板名称”,{数据});
读取模板文件,拼接数据(必须是json数据),自动将结果发送给浏览器
模板名称
直接写,路径在app.js
文件中已经配置过了(即views目录下的文件)
例
router.get('/',function(req,res){
var data = [
{"name":"aa","age":"11"},
{"name":"bb","age":"22"},
{"name":"cc","age":"33"},
{"name":"dd","age":"44"}
];
//模板渲染
res.render('list.ejs',{users:data});
});
res.download 下载
res.download('./xxx.doc');//下载当前目录下面的xxx.doc文件。
res.download('./xxx doc, 'yyy.doc');//下载当前目录下面的xxx.doc文件,并且重命名为yyy.doc.
res.redirect(‘目标’)
服务器端的跳转
res.redirect('www.baidu.com');
完整api
1. res.app:同req.app一样
2. res.append():追加指定HTTP头
3. res.set()在res.append()后将重置之前设置的头
4. res.cookie (name,value[,option]) :设置Cookie
opition:domain/expires/httpOnly/maxAge/path/secure/signed
5. res.clearCookie():清除Cookie
6. res.download():传送指定路径的文件
7. res.get():返回指定的HTTP头
8. res.json():传送JSON响应
9. res.jsonp():传送JSONP响应
10. res.location():只设置响应的Location HTTP头,不设置状态码或者closeresponse
11. res.redirect():设置响应的Location HTTP头,并且设置状态码302
12. res.send():传送HTTP响应
13. res.sendFile(path[,options][,fn]) :传送指定路的的文件-会自动根据文件extension 设定Content-Type
14.res.set():设置HTTP头,传入object可以一次设置多个头
15. res.status():设置HTTP的状态码
16. res.type():设置Content-type的MIME类型
请求对象
什么是请求对象
客户端向服务器发送数据的对象,包含请求头和请求主体
接收GRT方式传的值
req.query.参数名
例
router.get('/content.html',function(req,res){
var id=req.query.id;
res.send('获取到的ID是:'+id);
});
接收POST方式传的值
req.body.参数名
例:
router.post('/login.html',function(req,res){
var username=req.body.username;
var pwd=req.bady.pwd;
res .send('你传的用户名是:'+username+',你传的密码是:'+pwd);
});
匹配URL网址上的数据
在接请求地方去匹配,再通过语法进行接收,
语法:
req.params.参数名
请求:
localhost:/news/abc
例:
router.get('/news/:id',function(req,res){
//自动匹配news/后的值作为id的值
var id=req.params.id;
res. send('<h1>接收到的参数是: '+id+'</h1>');
});
完整api
1. req.app:当callback为外部文件时,用req.app访问express的实例
2. req.baseUrl:获取路由当前安装的URL路径
3. req.body/req.cookies:获得「请求主体」/Cookies
4. reg.fresh/req.sale:判断请求是否还「新鲜」
5. req.hostname/req.ip:获取主机名和IP地址
6. req.originalUrl:获取原始请求URL
7. req.params:获取路由的parameters
8. req.path:获取请求路径
9. req.protocol:获取协议类型
10. req-query:获取URL的查询参数串
11. req.route:获取当前匹配的路由
12. req subdomains:获取子域名
13. req.accpets():检查请求的Accept头的请求类型
14. req.acceptsCharsets/req.acceptsEncodings/req.acceptsLanguages
15. req.get():获取指定的HTTP请求头
16. req.is():判断请求头Content-Type的MIME类型
中间件
Express是一个自身功能极简,完全是由路由和中间件构成一个的web开发框架:从本质上来说,一个Express应用就是在调用各种中间件。
什么是中间件
中间件就是一个函数,位于客户端与路由之间,可以访问请求对象和响应对象,也可以调起下一个中间件。
自定义中间件
app.use(function(req,res,next){
res.send('我是中间件');
//next();
});
尾函数next
如果在中间件不调用next函数,整个请求响应流程就中止不会再往后面执行。
调用尾函数相当于调用下一个中间件,执行完以后自己的函数继续执行。
例:编写一个记录用户访问的中间件
app.use(function(req,res,next){
var fs=require('fs');
var ip=req.ip;
var time=new Date().toLocaleString();
var data=fs.readFileSync('./2019-12-09.1og');
data+='访问时间:'+time+'IP: '+ip+'\n';
fs.writeFileSync('./2019-12-09.1og',data);
next();|
});