初识express框架

目录

目录

1.express框架特性

2.send()

3.中间件

4. app.use中间件用法

5.中间件应用

6.错误处理中间件

7.异步函数捕获错误

8.模块化构建路由

9.GET参数获取 

10.POST参数获取

11.静态资源的处理

12.模板引擎

13.app.locals对象

14. 密码加密 bcrypt

15.Joi

16.formidable 

17.数据分页 mongoose-sex-page

18.mongoDB数据库添加账号


1.express框架特性

  • 提供了方便简洁的路由定义方式;
  • 对获取HTTP请求参数进行了简化处理;
  • 对模板引擎支持度高,方便渲染动态HTML页面;
  • 提供了中间件机制有效控制HTTP请求;
  • 拥有大量第三方中间件对功能进行扩展。

2.send()

const express = require('express');
const app = express();
app.get('/',(req,res)=>{
    res.send('这里是首页');
    //send()
    //1.send方法内部会检测响应内容的类型;
    //2.send方法会自动设置http状态码
    //3.send方法会自动设置响应的内容类型及编码
})
app.get('/list',(req,res)=>{
    res.send({name:'cxc'})
})
app.listen(80);
console.log('express框架启动的服务器已启动')

3.中间件

中间件就是一堆方法,可以接收客户端发来的请求,可以对请求作出响应,也可以将请求继续交给下一个中间件继续处理。

const express = require('express');
const app = express();
app.get('/request',(req,res,next)=>{
    req.name = 'cxc';
    next();
})
app.get('/request',(req,res)=>{
    res.send(req.name)
})

app.listen(80);
console.log('服务器部署成功')

4. app.use中间件用法

  • app.use 匹配所有的请求方式,可以直接传入请求处理函数,代表接收所有的请求;
  • app.use 第一个参数也可以传入请求地址,代表不论什么请求方式,只要是这个请求地址就接收这个请求;
const express = require('express');
const app = express();
app.use((req,res,next)=>{
    console.log('app.use中间件被执行了')
    next();
})
app.use('/request',(req,res,next)=>{
    console.log('app.use /request中间件被执行了');
    next();
})
app.use('/list',(req,res)=>{
    res.send('/list');
})
app.get('/request',(req,res,next)=>{
    req.name = 'cxc';
    next();
})
app.get('/request',(req,res)=>{
    res.send(req.name)
})

app.listen(80);
console.log('服务器部署成功')

5.中间件应用

  • 路由保护,客户端在访问需要登录的页面时,可以先使用中间件判断用户登录状态,用户如果未登录,则拦截请求,直接响应,禁止用户进入需要登录的界面;
  • 网站维护公告,在所有路由的最上面定义接收所有请求的中间件,直接为客户端作出响应,网站正在维护中;
  • 自定义404页面
const express = require('express');
const app = express();
/*//网站维护
    app.use((req,res,next)=>{
        res.send('网站正在维护中');
    })*/
    //模拟登录状态识别
    app.use('/admin',(req,res,next)=>{
        let login = true;
        if(login){
            next();
        }else {
            res.send('您还没有登录');
        }
    app.use('/admin',(req,res,next)=>{
        res.send('您已成功登录');
    })
    //自定义404
    app.use((req,res,next)=>{
        res.status(404).send('您访问的页面不存在')
    })
})
app.listen(80);
console.log('服务器部署成功')

6.错误处理中间件

  • 在程序执行的过程中,不可避免的会出现一些无法预料的错误,比如文件读取失败,数据库连接失败。错误处理中间件是一个集中处理错误的地方;
  • 当程序出现错误时,调用next()方法,并且将错误信息通过参数的形式传递给next()方法,即可触发错误处理中间件。 
const express = require('express');
const fs = require('fs');
const app = express();

app.get('/index',(req,res,next)=>{
  // throw new Error('程序发生了未知错误');
    fs.readFile('./demo.js','utf8',(err,result)=>{      //手动调用next方法,传递err错误给错误处理中间件
        if(err != null){
            next(err);
        }else {
            res.send(result)
        }
    })
})
//错误处理中间件(只能捕获同步代码出错)
app.use((err,req,res,next)=>{
    res.status(500).send(err.message);
})

app.listen(80);
console.log('服务器部署成功')

7.异步函数捕获错误

在node.js中,异步API的错误信息都是通过回调函数获取的,支持Promise对象的异步API发生错误可以通过catch方法捕获。

try catch 可以捕获异步函数以及其他同步代码在执行过程中发生的错误,但是不能捕获其他类型的API发生的错误。

const express = require('express');
const fs = require('fs');
const app = express();
const promisify = require('util').promisify;
const readFile = promisify(fs.readFile);
app.get('/index', async (req,res,next)=>{
    try{
        await readFile('./77.js');
    }catch (e) {
        next(e)
    }
})
//错误处理中间件(只能捕获同步代码出错)
app.use((err,req,res,next)=>{
    res.status(500).send(err.message);
})

app.listen(80);
console.log('服务器部署成功')

8.模块化构建路由

const express = require('express');
const app  = express();
const home = express.Router();  //创建路由对象
app.use('/home',home);  //将路由和请求路径进行匹配
home.get('/index',(req,res)=>{  //在home路由下继续创建二级路由
    res.send('欢迎来到博客展示页面');
})

app.listen(3000);
console.log('服务器创建成功')

 admin.js

const express = require('express');
const admin = express.Router();
admin.get('/index',(req,res)=>{
    res.send('欢迎来到博客管理页面')
})

module.exports = admin;

home.js

const express = require('express');
const home = express.Router();
home.get('/index',(req,res)=>{
    res.send('欢迎来到博客展示页面')
})
module.exports = home;

app.js 

const express = require('express');
const app = express();
const admin = require('./router/admin');
const home = require('./router/home');
app.use('/admin',admin);
app.use('/home',home);
app.listen(3000)

9.GET参数获取 

第一种:express框架中使用req.query即可获取GET参数,框架内部会将GET参数转换为对象并返回。

//GET参数的获取
const express = require('express');
const app = express();

app.get('/index',(req,res)=>{
    res.send(req.query)
})

app.listen(3000)

 第二种:

const express = require('express');
const app = express();
app.get('/index/:id/:name/:age',(req,res)=>{ //访问的时候必须传递所有参数 否则无法访问
    res.send(req.params)
})
app.listen(3000);

10.POST参数获取

express中接收参数需要借助第三方包 body-parser

const express = require('express');
const bodyParser = require('body-parser');
const app = express();
//拦截所有请求
//extended:false 方法内部使用querystring模块处理请求参数的格式
//extended:true  方法内部使用第三方模块qs处理请求参数的格式
app.use(bodyParser.urlencoded({extended:false}))
app.post('/add',(req,res)=>{
    //接收post请求参数
    res.send(req.body)
})
app.listen(3000);

11.静态资源的处理

通过express内置的express.static可以方便地托管静态文件,例如img,css,js文件等。

const express = require('express');
const app = express();
const path = require('path');
app.use('/index',express.static(path.join(__dirname,'public')))
app.listen(3000);

12.模板引擎

为了使art-template模板引擎能够更好的和express框架配合,模板引擎官方在原art-template模板引擎的基础上封装了express-art-template 。使用npm i art-template express-art-template命令进行同时安装。

const express = require('express');
const app = express();
const path = require('path');
//告诉express框架使用什么模板引擎渲染什么后缀的模块文件
app.engine('art',require('express-art-template'));
//告诉express框架模板存放的位置是什么
app.set('views',path.join(__dirname,'views'));
//告诉express框架模板的默认后缀是什么
app.set('view engine','art');

app.get('/index',(req,res)=>{
    res.render('index',{
        mes:'渲染模板引擎'
    })
})
app.get('/list',(req,res)=>{
    //1.拼接模板路径
    //2.拼接模板后缀
    //3.哪一个模板和哪一个数据进行拼接
    //4.将拼接结果响应给客户端
    res.render('list',{
        mes:'list'
    })
})
app.listen(3000)

13.app.locals对象

将变量设置到app.locals对象下面,这个数据在所有的模板中都可以获取到。

const express = require('express');
const app = express();
const path = require('path');
app.engine('art',require('express-art-template'));
app.set('views',path.join(__dirname,'views'));
app.set('view engine','art');
app.locals.users=[{
    name:'cxc',
    age:22
},{
    name:22,
    age:22
}]
app.get('/index',(req,res)=>{
    res.render('index',{
        mes:'模板引擎渲染'
    })
})
app.listen(3000)

 index.art

{{ mes }}
<ul>
    {{each users}}
    <li>{{$value.name}}</li>
    <li>{{$value.age}}</li>
    {{/each}}
</ul>

14. 密码加密 bcrypt

  • 哈希加密是单线程加密方式:只能单向加密,不能解密;
  • 在加密的密码中加入随机字符串可以增加密码被破解的难度;
  • bcrypt依赖的其他环境:
    • python 2.x;
    • node-gyp     npm i -g node-gyp;
    • windows-build-tools     npm i --global --production windows-build-tools     (管理员POWERSHALL安装)
  • 环境变量配置

  • npm i bcrypt   (管理员POWERSHALL安装)
const bcrypt = require('bcrypt');
async function run() {
    /*生成随机字符串
    gensalt方法接收一个数值作为参数
    默认为10 数值越大越复杂
    返回生成的随机字符串*/
    const salt = await bcrypt.genSalt(15);
    /*对密码进行加密
        1.要进行加密的明文;
        2.随机字符串;
        3.返回值是加密后的密码*/
    const result = await bcrypt.hash('12354',salt);
    console.log(salt,result)
}
run();
//密码比对:let isEqual = await bcrypt.compare('明文密码','加密密码')

15.Joi

JavaScript对象的规则描述语言和验证器 

const Joi = require('joi');
const schema = {
    username:Joi.string().required().min(2).max(7).error(new Error('username属性验证不通过')),
    birth:Joi.number().min(2000).max(2020).error(new Error('password属性验证不过')),
    role:Joi.string().required().valid('admin','normal').error(new Error('角色名非法')) //输入值必须包含某一值
}
async function run() {
    try{
        await Joi.validate({username:'222',birth:2017,role:'admin'},schema)
    }catch (e) {
        console.log(e.message);
        return
    }
    console.log('验证通过')
}
run();

/*   第二种捕获错误信息  validate返回promise对象,可使用.then .catch捕获
Joi.validate({username:'222',birth:20171},schema)
.then(()=>console.log('验证通过'))
.catch(err=>console.log(err.message,'验证失败'))
*/

16.formidable 

作用:解析表单,支持get请求参数 post请求参数 文件上传

const formidable = require('formidable');
const form = new fomidable.IncomingForm(); //创建表单解析对象
form.upload = "";//设置文件上传路径
form.keepExtensions = false ;//是否保留保单上传的扩展名
form.parse(req,(err,fields,files)=>{
    //fields 存储普通请求参数;
    //files 存储上传的文件信息
})
 

const {Article} = require('../../model/article');
const formidable = require('formidable');
const path = require('path');
module.exports = (req,res)=>{
    const form = new formidable.IncomingForm(); //创建表单解析对象
    form.uploadDir = path.join(__dirname,'../','../','public','uploads');
    form.keepExtensions = true; //是否保留后缀 默认false
    form.parse(req, async (err,fields,files)=>{
       // res.send(files.cover.path.split('public')[1]);
      await  Article.create({
            title: fields.title,
            author: fields.author,
            publishDate: fields.publishDate,
            cover: files.cover.path.split('public')[1],
            content: fields.content
        })
        res.redirect('/admin/article');
    })

}

17.数据分页 mongoose-sex-page

const pagination = require('mongose-sex-page') ;

pagination(集合构造函数).page(1).size(20).display(8).exec();

const {Article} = require('../../model/article');
const pagination = require('mongoose-sex-page');
module.exports = async (req,res)=>{
    const page = req.query.page;
    req.app.locals.currentLink = 'article';
    //page 指定当前页
    //size 每页显示的条数
    //display 指定要显示的页码数量
    //exec 向数据库中发送查询请求
    const articles =  await pagination(Article).find().page(page).size(2).display(3).populate('author').exec(); //多集合(表)联合查询
    const count = await Article.estimatedDocumentCount({});
    res.render('admin/article',{
        articles,count
    })
}

18.mongoDB数据库添加账号

1. 以系统管理员的方式运行powershell

2. 连接数据库 mongo

3. 查看数据库 show dbs

4. 切换到admin数据库 use admin

5. 创建超级管理员账户 db.createUser()

6. 切换到blog数据 use blog

7. 创建普通账号 db.createUser()

8. 卸载mongodb服务

         1. 停止服务 net stop mongodb

         2. mongod --remove

9. 创建mongodb服务

          mongod --logpath="D:\Program Files\MongoDB\Server\4.1\log\mongod.log" --dbpath="D:\Program
          Files\MongoDB\Server\4.1\data
" --install –-auth

10. 启动mongodb服务 net start mongodb

11. 在项目中使用账号连接数据库

          mongoose.connect('mongodb://user:pass@localhost:port/database')

 

Windows PowerShell
版权所有 (C) Microsoft Corporation。保留所有权利。

尝试新的跨平台 PowerShell https://aka.ms/pscore6

PS C:\WINDOWS\system32> mongo
MongoDB shell version v4.2.6
connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("9f520f3d-d542-4a52-b6e4-10de3945232c") }
MongoDB server version: 4.2.6
Server has startup warnings:
2020-06-04T16:03:35.978+0800 I  CONTROL  [initandlisten]
2020-06-04T16:03:35.978+0800 I  CONTROL  [initandlisten] ** WARNING: Access control is not enabled for the database.
2020-06-04T16:03:35.978+0800 I  CONTROL  [initandlisten] **          Read and write access to data and configuration is unrestricted.
2020-06-04T16:03:35.978+0800 I  CONTROL  [initandlisten]
---
Enable MongoDB's free cloud-based monitoring service, which will then receive and display
metrics about your deployment (disk utilization, CPU, operation statistics, etc).

The monitoring data will be available on a MongoDB website with a unique URL accessible to you
and anyone you share the URL with. MongoDB may use this information to make product
improvements and to suggest MongoDB products and deployment options to you.

To enable free monitoring, run the following command: db.enableFreeMonitoring()
To permanently disable this reminder, run the following command: db.disableFreeMonitoring()
---

> show dbs
admin       0.000GB
blog        0.000GB
config      0.000GB
local       0.000GB
nodeCases   0.000GB
playground  0.000GB
> use admin
switched to db admin
> db.createUser({user:'root',pwd:'root',roles:['root']})
Successfully added user: { "user" : "root", "roles" : [ "root" ] }
> use bolg
switched to db bolg
> use blog
switched to db blog
> db.createUser({user:'cxc',pwd:'777',roles:['readWrite']})
Successfully added user: { "user" : "cxc", "roles" : [ "readWrite" ] }
> exit
bye
PS C:\WINDOWS\system32> net stop mongodb
MongoDB Server (MongoDB) 服务正在停止.
MongoDB Server (MongoDB) 服务已成功停止。

PS C:\WINDOWS\system32> mongod --remove
2020-06-13T23:10:44.617+0800 I  CONTROL  [main] Automatically disabling TLS 1.0, to force-enable TLS 1.0 specify --sslDisabledProtocols 'none'
2020-06-13T23:10:45.713+0800 W  ASIO     [main] No TransportLayer configured during NetworkInterface startup
2020-06-13T23:10:45.714+0800 I  CONTROL  [main] Trying to remove Windows service 'MongoDB'
2020-06-13T23:10:45.722+0800 I  CONTROL  [main] Service 'MongoDB' removed
PS C:\WINDOWS\system32> mongod --logpath='D:\Program Files\MongoDB\Server\4.2\log\mongod.log' --dbpath='D:\Program Files\MongoDB\Server\4.2\data' --install --auth
2020-06-13T23:13:51.666+0800 I  CONTROL  [main] log file "D:\Program Files\MongoDB\Server\4.2\log\mongod.log" exists; moved to "D:\Program Files\MongoDB\Server\4.2\log\mongod.log.2020-06-13T15-13-51".
PS C:\WINDOWS\system32> net start mongoDB
MongoDB 服务正在启动 ..
MongoDB 服务已经启动成功。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值