Express框架

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应用,客户端断开的情况下,应用也能正常工作

  1. 安装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
    
  2. 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

测试项目

打开浏览器输入localhost127.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目录下的所有请求,响应数据。

实现步骤:

  1. 创建一个vip路由模块

  2. 编写路由模块的代码(在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

  1. 将编写好的路由模块引入到主模块中,由主模块分配对应的请求到该模块中去处理(主模块为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();|
});