Express 框架 知识总结
express框架
- 使用send()方法代替end
- 自动设置http状态码,
- 自动检测响应内容的类型,
- 设置相应内容类型及其编码
中间件
- 一堆方法,中间件方法,请求处理函数
- 使用
app.use
方法,匹配所有的方式 - 应用
- 路由保护
- 网站维护
- 自定义404状态码
查看代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31const express = require('express');
// 创建网站服务器
const app = express();
// app.get('/',(req,res)=>{
// // 使用send()方法代替end,自动设置http状态码,自动检测响应内容的类型,对那个设置相应内容类型及其编码
// res.send('启动成功')
// })
// app.get('/list',(req,res)=>{
// res.send({name:'张是',age:1})
// })
// 中间件,使用next继续执行
// 使用app.use方法,匹配所有的请求方式,可以自定义404界面
app.use('/',(req,res,next)=>{
console.log(2);
next()
})
app.get('/',(req,res,next)=>{
req.name = 'zs'
next()
})
app.get('/',(req,res)=>{
res.send(req.name)
})
// 可以自定义404界面
app.use((req,res,next)=>{
res.status(404).send('当前访问的页面不存在')
})
app.listen(3000)
console.log('网站服务器启动成功');
错误处理中间件
- 统一处理错误
app.use((err,req,res,next)=>{})
- 异步代码执行出错无法读取,手动使用next方法
同步代码
1
2
3
4
5
6
7// 错误处理中间件
app.get('/index',(req,res)=>{
throw new Error('程序发生了未知错误')
})
app.use((err,req,res,next)=>{
res.status(500).send(err.message)
})异步代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14// 错误处理中间件
app.get('/index',(req,res,next)=>{
// throw new Error('程序发生了未知错误')
fs.readFile('./dawdaw','utf8',(err,result)=>{
if(err!=null){
next(err)
}else{
res.send(result)
}
})
})
app.use((err,req,res,next)=>{
res.status(500).send(err.message)
})
捕获错误
try catch
语句- 捕获异步函数错误
查看答案
1
2
3
4
5
6
7
8
9
10
11const promisify = require('util').promisify
app.get('/index',async (req,res,next)=>{
try{
await readFile('./add.js')
}catch(ex){
next(ex)
}
})
app.use((err,req,res,next)=>{
res.status(500).send(err.message)
})
构造模块化路由
express.Router()
创建路由对象- 将路由请求路径进行匹配
查看答案
1 | // 路由访问二级 |
get/post参数的获取
req.query
获取get 的请求参数- post的请求参数 使用第三方模块
body-parser
req.body
获取post的请求参数
express路由参数
:
后面写要传递的对象参数params
查看答案
1
2
3app.get('/index/:id/:name/:age',(req,res)=>{
res.send(req.params);
})
静态资源访问
express.static('public')
对静态资源进行处理,pubic 表示静态资源所在的路径- 格式
app.use(express,static(path.join(__dirname,'public'))
模板引擎
all-template express-art-template
- 渲染某个后缀文件时 使用
express-art-tenplate
查看答案
1 | const express = require('express') |
app.locals对象
- 使用app.locals方法可以在所有的模板下可以获取到
查看答案
1
2
3
4
5
6
7
8
9app.locals.users = [{
name:'hello',
age:13,
sex:'1'
},{
name:'张三',
age:20,
sex:0
}]
注意
- 静态资源是由浏览器进行解析,
- 子模版的相对路径就是当前文件,因为它是由模板引擎解析的
密码加密 bcypt
- 哈希密码 单程解密
bcrypt
方法 生成随机字符串,hash方法进行加密- 或者使用
crypto
实现md5简单加密,可以进行二次加密或者添加字符串进行加密处理
查看答案
1 | const md5Crypto=(str)=>{ |
- 在进行密码比对时可以使用(bcypt.compare(暗文密码,明文密码)
cookie和session
- cookie中的数据是以域名的形式进行区分的
- cookie中的数据是有过期事件的,会随请求被发送到服务器端
- session 对象
- 使用
redirect
方法重定向到用户列表页面 - 登录拦截 使用中间件重定向 判断session中是否存在某个属性
- 使用clearCookie删除页面已经保存的cookie 然后对页面进行重定向
Joi第三方模块
- JavaScript对象的规则描述语言和验证器
- 注意joi的版本问题 【no function解决方法】
- validate方法 为异步函数 ,对用户提交的信息进行判断并返回错误
查看答案
1 | const Joi = require('joi') |
对页面进行分页
- 使用
countDocuments({})
来获取数据库集合的总数 - 并且定义一个总的页码
- 使用limit限制,使用skip跳过n个数据
-
有隐式运算查看答案
1
2
3
4
5
6
7
8
9
10
11<!--
<% for(var i=1;i<=pages;i++){%>
<li><a href="/admin/user?page=<%=i%>"><%=i%></a></li>
<%}%>
-->
下一页
<li style="display:<%= page-0+1 > pages ? 'none' : 'inline' %>">
<a href="/admin/user?page=<%= page-0+1 %>">
<span>»</span>
</a>
</li>
标识编码
- 使用
res.app.locals.currentLink
来标识当前选中的页面 - 可以使用js来改变当前的选中情况
- 表单enctype属性表示编码
- 指定表单数据的编码类型 原型
application/x-www-form-urlencoded
- 加个表单对的数据编码成二进制的类型
multipart/form-data
formidable解析表单
- 解析表单,支持
get
请求参数,post
请求参数,文件上传 - 使用
form.keepExtensions
保留表单上传文件的扩展名 form.uploadDir
表示设置文件的上传路径- 可以对表单提交的二进制信息类型进行解析
- fields 保存普通的表单信息 files 表示文件的信息
查看答案
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21const formidable = require("formidable")
// 导入第三方模块 formidable
const path = require('path')
module.exports = (req,res) =>{
// 创建表单解析对象
const form = new formidable.IncomingForm()
// 配置上传文件的后缀
form.uploadDir = path.join(__dirname,'../','../','public','uploads')
// 保留上传文件的后缀
form.keepExtensions = true
// 解析表单
form.parse(req,(err,fields,files) =>{
// 1. err表示错误对象,如果表单解析失败 err里面存储错误信息 如果表单解析成功
// fields表示普通的表单数据
// files表示保存了和上传文件相关的数据
res.send(files)
})
// res.send('ok')
}
文件读取
FileReader()
readAsDataURL('文件')
- 并且
readAsDataURL
为异步函数无法直接获取信息,需要调用 onload来返回读取的结果查看答案
1
2
3
4
5
6
7
8
9
10
11
12let file = document.querySelector('#file');
let preview = document.querySelector('#preview')
file.onchange = function(){
let reader = new FileReader();
// 用户选择的文件列表
reader.readAsDataURL(this.files[0]);
// 监听onload事件
reader.onload = function(){
// 将获取到的文件结果显示在页面中
preview.src = reader.result
}
}
数据分页
- 使用第三方模块
mongoose-sex-page
- page 表示当前页 size 表示每页显示数据的条数,display表示客户端显示的页码 total数据总数 pages 总页数
$index
表示当前某个标签的索引号- 在进行内容渲染时 使用正则将内容中html标签去除 replace方法
/<\/?.+?>/g
,并且使用字符串的截取将文本溢出省略substr(0,150)
如果文中出现乱码可以将返回的数据以原文输出方式显示
查看答案
1 | const {Article} = require('../../model/article') |
- 可以使用自定义的参数来进行上下页面的切换,
- 比如通过对地址栏数据的获取,判断当前页面所对应的页码,然后将此页码进行判断比如进行上一页的切换,如果页面-1小于1则使得当前的地址栏中的页码数等于一,反之使得在当前页码的基础上加一,下一页雷同 注意隐式算法
- 第二种方法使用css将其隐藏,达到某个页码时将此模块显示
- 使用第三方模块 pagination-sex-page下的参数执行第一步操作 ,在进行上下页切换时可以使用模块化语言 使用if判断 如果满足条件才让它显示出来
mongoDB数据库添加账号
- 查看数据库 连接数据库
mongo
查询数据库show dbs
- 切换到admin数据库
use admin
- 创建超级管理员账号
db.createUser({user:'root',pwd:'root',roles:['root']})
- 切换到blog数据
user blog
- 创建普通账号
db.createUser({user:'xxxx',pwd:'xxxx',roles:['readWrite']})
- 移除数据库 先停止
net stop mongodb
在使用mongod --remove
- 创建数据库环境
mongod --logpath="D:\mongoDB\install\server\log\newmongod.log" --dbpath="D:\mongoDB\install\server\data" --install --auth
- 连接数据库 使用
mongodb://普通用户名:用户名密码@localhost:端口号/要连接数据库名称
- 启动数据库
net start mongodb
开发环境和生产环境
- 使用process.env.某个指定的对象来判断当前的环境情况
- morgan(‘dev’) 在开发环境中将客户端发送到服务器端的请求信息打印到控制台中,只能在开发环境中使用
- production 生产环境
config模块
- 将不同运行环境下的应用配置信息抽离到单独的文件中,模块内部字段判断当前的运行环境,并读取对应的配置信息
- 创建config文件夹 default development production 三个json文件,通过require的方法导入
- get方法,
- 这个方法可以自动判断当前的运行环境,并根据相对应的配置信息返回,如果该环境配置下没有匹配到某个指定信息,则在其他的配置信息中自动查询
- 将敏感配置信息存储在环境变量中
custom-environment-variables.json
自定义环境变量
评论的创建
- 创建评论的集合规则 将评论属性的id值与文章的内容id进行关联, 设置其属性为 mongoose.Schema.Types.Objected, ref 为所关联集合名称
- 建立评论的路由 只有当用户登录之后才可以使用评论的模块 创建评论的模块
- 获取用户在文本框内输入的内容,将此内容通过所在的文章的id值新建一个数据库或者上传到文章的数据库页面
- 用户需要登录后才能使用评论 在用户登录后判断如果登录的用户是超级管理员则将页面重定向到博客惯例页面如果是普通用户则将页面重定向到文章的首页
- 将登录用户的role存储到session中,在对session进行拦截判断 并且将登录后的首页信息改为用户的信息对评论的状态进行配置,当用户登录后 在本地已经存储到一个userInfo,判断userInfo是否存在,如果存在则将评论模块呈现出来,如果未登录则将评论状态和首页头部的用户状态关闭
- 渲染评论页面直接在文章页面渲染
- 将用户信息渲染到页面页 创建评论路由 根据评论集合创建规则,上传集合对象 post请求后将页面重定向未当前页面
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Harry の 心 阁!
评论