博客

290 阅读7分钟

1. 项目环境搭建

1.1 多人博客管理系统

  1. 博客内容展示
  2. 博客管理功能

1.2 案例初始化

  1. 建立项目所需文件夹

    • public 静态资源
    • model 数据库操作
    • route 路由
    • views 模板
  2. 初始化项目描述文件

    • npm init -y
  3. 下载项目所需第三方模块

    npm install express mongoose art-template express-art-template

    • express: 用来创建网站服务器和路由
    • mongoose: 用来操作数据库
    • art-template: 用来渲染模板
  4. 创建网站服务器

  5. 构建模块化路由

  6. 构建博客管理页面模板

错误记录

在构建模块化路由时app.use('/home', home)误写成app.use('./home', home),导致页面一直返回Cannot GET,特此记录。

笔记

在模板路径中外链资源要写绝对路径,/代表绝对路径。

Cannot set headers after they are sent to the client

出现这个错误就表示,在一个关闭的链接上又做了一些操作,翻看代码,删除一个res.send()后解决。

2. 项目功能实现

2.1 登录

  1. 创建用户集合,初始化用户
    1. 连接数据库
    2. 创建用户集合
    3. 初始化用户
  2. 为登录表单项设置请求地址、请求方式以及表单项name属性
  3. 当用户点击登录按钮时,客户验证用户是否填写了登录表单
  4. 如果其中一项没有输入,阻止表单提交
  5. 服务器端接收请求参数,验证用户是否填写了登录表单
  6. 如果其中一项没有输入,为客户端做出响应,阻止程序向下执行
  7. 根据邮箱地址查询用户信息
  8. 如果用户不存在,为客户端做出响应,阻止程序向下执行
  9. 如果用户存在,,将用户名和密码进行比对
  10. 比对成功,用户登录成功
  11. 比对失败,用户登录失败

2.2 新增用户

  1. 为用户列表页面的新增用户按钮添加链接
  2. 添加一个链接对应的路由,在路由处理函数中渲染新增用户模板
  3. 为新增用户表单指定请求地址、请求方式、为表单项添加name属性
  4. 增加实现添加用户的功能路由
  5. 接收到客户端传递过来的请求参数
  6. 对请求参数的格式进行验证
  7. 验证当前要注册的邮箱地址1是否已经注册过
  8. 对密码进行加密处理
  9. 将用户信息添加到数据库中
  10. 重定向页面到用户列表页面

2.3 数据分页

当数据库中的数据非常多是,数据需要分批次显示,这时就需要用到数据分页功能。

image.png

分页功能核心要素:

  1. 当前页,用户通过点击上一页或者下一页或者页码产生,客户端通过get参数方式传递到服务器端
  2. 总页数,根据总页数判断当前页是否为最后一页,根据判断结果做响应操作

2.4 用户信息修改

  1. 将要修改的用户ID传递到服务器端
  2. 建立用户信息修改功能对应的路由
  3. 接收客户端表单传递过来的请求参数
  4. 根据id查询用户信息,并将客户端传递过来的密码和数据库中的密码进行比对
  5. 如果比对失败,对客户端做出响应
  6. 如果密码对比成功,将用户信息更新到数据库中

2.5 用户信息删除

  1. 在确认删除框中添加隐藏域用以存储要删除用户的ID值
  2. 为删除按钮添自定义属性用以存储要删除用户的ID值
  3. 为删除按钮添加点击事件,在点击事件处理函数中获取自定义属性中存储的ID值并将ID值存储在表单的隐藏域中
  4. 为删除表单添加提交地址以及提交方式
  5. 在服务器端建立删除功能路由
  6. 接收客户端传递过来的id参数
  7. 根据id删除用户

2.6 开发环境与生产环境

什么是开发环境与生产环境

环境,就是指项目运行的地方,当项目处于开发阶段,项目运行在开发人员的电脑上,项目所处的环境就是开发环境。当项目开发完成以后,要将项目放到真实的网站服务器电脑中运行,项目所处的环境就是生产环境。

为什么要区分开发环境与生产环境

因为在不同的环境中,项目的配置是不一样的,需要在项目代码中判断当前项目运行的环境,根据不同的环境应用不同的项目配置。

3. 项目包含的知识点

3.1 密码加密 bcrypt

哈希加密是单程加密方式:1234 => abcd 在加密的密码中加入随机字符串可以增加密码被破解的难度。

// 导入bcrypt模板
const bcrypt = require('bcrypt');
// 生成随机字符串 gen => generate 生成salt 盐
let salt = await bcrypt.genSalt(10);
// 使用随机字符串对密码进行加密
let pass = await bcrypt.hash('明文密码', salt);
// 密码比对
let isEqual = await bcrypt.compare('明文密码', '加密密码');

bcrypt依赖的其他环境

  1. python 2.x
  2. node-gyp npm install -g node-gyp
  3. windows-build-tools npm install --global --production windows-buil-tools

3.2 cookie与session

cookie:浏览器在电脑硬盘中开辟的一块空间,主要供服务器端存储数据。

  • cookie中的数据是以域名的形式进行区分的。
  • cookie中的数据是有过期时间的,超过时间数据会被浏览器自动删除。
  • cookie中的数据会随着请求被自动发送到服务器端。

image.png

session: 实际上就是一个对象,存储在服务器端的内存中,在session对象中也可以存储多条数据,每一条数据都有一个sessionid做为唯一标识。

image.png

例子: sessionId存储在cookie中,相当于将卡号写在一张卡上,session对象相当于记录本,客户端发送请求到服务器端携带cookie信息,相当于客人在店里购物出示卡片,用来证明客人的身份。

cookie相当于服务器端发给客户端的验证身份的标识,每一次客户端访问服务器端的时候都要带着这个标识,以证明自己的身份。服务器端的session就是记录身份的对象,服务器端收到客户端发来的sessionId后会在session对象中查找语句。

利用cookie和session实现登录功能

在node.js中需要借助express-session实现session功能。

const session = require('express-session');
app.use(session({ secret: 'secret key' }));

当网站重启的时候,服务器端的session对象就会失效

express 方法下的重定向

redirect('需要跳转的地址')

使用locals存储对象

将用户信息存放在locals公共对象下,在所有的模板中都可以访问到userInfo req.app.locals.userInfo = user; 在需要插入的art模板下: {{userInfo && userInfo.username}}

3.3 Joi

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

  1. 引入joi模块
  2. 定义对象的验证规则Joi.object({})
  3. 通过schema.validateAsync({})实施验证
  • string():是字符串类型
  • alphanum():字母类型
  • number(): 数字类型
  • required():在joi中如果不加required,则都不是必填项,加了required就是必填项
  • error(new Error('错误信息')):自定义错误信息
const Joi = require('joi');
const schema = Joi.object({
    username: Joi.string().alphanum().min(3).max(30).required().error(new Error(‘错误信息’)),
    password: Joi.string().regex(/^[a-zA-Z0-9]{3,30}$/),
    access_token: [Joi.string(), Joi.number()],
    birthyear: Joi.number().integer().min(1900).max(2013),
    email: Joi.string().email()
});
try {
        // 实施验证
        await schema.validateAsync({ username: 'ab' });
    } catch (ex) {
        console.log(ex);
        return;
    }
    console.log('验证通过');

image.png