node 博客项目
创建后端服务器
-
先创建一个
nodejs
文件, -
使用
npm -y init
快速生成package.json
文件,方便管理插件 -
使用
npm install express
命令下载第三方模块,可以快速创建一个本地服务器
//使用模块前必须先导入
const express = require('express')
//调用express函数返回的对象,便可快速创建本地服务器
const app = express()
//绑定端口,这样就已经创建好了一个本地服务器,可以通过http://localhost:3000访问
app.listen(3000)
连接数据库
-
使用
npm install mongoose
可以连接mongodb数据库 -
使用
mongoos
中的connect
方法可以连接数据库
//导入mongoo模块
const mongoose = require('mongoose')
//如果数据库没有设置了登陆验证,user、password可以省略
//27017是数据库端口号,可省略
//dbname是你要连接的数据库名称
//返回的结果是一个promise对象
mongoose.connect('mongodb:user:password@localhost:27017/dbname'
//第二个参数是一个对象,如果不加会弹出警告,但是不影响使用
{ useNewUrlParser: true, useUnifiedTopology: true }).then(()=>{
console.log('连接数据库成功')
})
创建集合规则
-
集合规则就相当于对数据库中各个字段要求的规范
-
使用
new mongoose.Schema
可以创建集合 -
这个函数接收的参数是一个对象
//创建用户集合规则
const userSchema = new mogoose.Schema({
name:{
//传入的name字段必须是字符串类型
type:String
//表示改字段为必填属性
required:true
},
password: {
type: String,
required: true
},
email: {
type: String,
required: true
},
role: {
type: String,
//default表示默认值
default: 'normal'
},
createDate: {
type: String,
default: new Date
}
},
{
//如果不加这个参数,在数据库中会多出一个_v字段
versionKey: false
}
)
创建用户集合
-
使用上一步创建好的用户集合规则可以创建用户集合
-
使用
mongoose.model
方法可以创建用户集合
//第一个参数为要创建的数据库名称
//第二个参数是要使用的集合规则
//第三个参数可以省略,但是省略或创建的数据库名称会改变 User => users
//第三个参数可以强制规定数据库的名字,建议加上
const User = mongoose.model('User',userSchema,'users')
用户密码加密
-
使用第三方模块
bcrypt
来加密用户密码以及密码比对 -
npm install bcrypt
下载安装后使用require
引入-
const bcrypt = require(‘bcrypt’)
-
-
加密密码主要有三个步骤
-
生成加密盐
-
const salt = await bcrypt.genSalt(10)
-
-
密码加密
-
const pwd = await bcrypt.hash(‘admin’, salt)
-
-
替换用户密码
-
-
; (async () => { // 引入密码加密插件 const bcrypt = require('bcrypt') // 密码加密盐 const salt = await bcrypt.genSalt(10) const pwd = await bcrypt.hash('admin', salt) })() //这个加密插件返回的都是promis对象,可以用异步函数的形式来简化操作
创建用户
-
使用用户集合中的
create
方法便可以创建用户
//create函数接收一个对象为参数
//这个对象的内容就是集合规则中规定的字段
//返回的是一个promis对象
User.create({
name:'张三',
//生成后的加密密码
password:pwd,
email:'zhangsan@qq.com',
role:'admin'
}).then(()=>{
console.log('创建用户成功')
})
//建议在使用一次后就注释这个代码,不然每次启动项目就会创建这个用户
- 数据库的操作可以写在另一个文件中,与创建服务器文件分开,方便管理,使用
model.exprots
导出用户集合函数便可
vue脚手架创建前端项目
- 使用
npm install -g @vue/cli
全局下载安装vue脚手架工具 - 完成后,可以使用
vue create 项目名字
和vue ui
两种方式来创建项目 - vue 创建项目,见另一篇博客
引入ElementUI
- 使用
npm i element-ui -S
安装项目 - 在前端项目
main.js
入口文件中引入样式文件import 'element-ui/lib/theme-chalk/index.css'
- 在和
main.js
文件平级的目录下可以创建一个ElementUI.js
文件,按需导入组件,然后在main.js
中导入便可
安装axios
-
使用命令
npm install axios
安装axios
-
安装完成后,在
main.js
文件中导入-
import axios from ‘axios’
-
-
配置axios默认请求路径(可省略,但写请求路径是会更麻烦)
-
//这个地址就是服务器端访问的地址
axios.defaults.baseURL = ‘http://localhost:3000’
-
-
设置发送请求时携带请求头
-
axios.defaults.withCredentials = true
-
-
在全局中挂载
axios
-
Vue.prototype.$http = axios
//下次使用时,只需要this.$http
-
登陆
####前端页面
-
使用
ElementUI
中的el-card
组件,可以快速布局 -
使用
el-form
组件可以快速生成一个表单-
Form 组件提供了表单验证的功能,只需要通过
rules
属性传入约定的验证规则,并将 Form-Item 的prop
属性设置为需校验的字段名即可 -
<el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm" hide-required-asterisk > <el-form-item label="用户邮箱" prop="email"> <el-input v-model="ruleForm.email"></el-input> </el-form-item> <el-form-item label="用户密码" prop="password"> <el-input v-model="ruleForm.password" type="password"></el-input> </el-form-item> </el-form> <div class="btnBox"> <el-button type="primary" size="large" @click="login()">登陆</el-button> <el-button type="info" size="large" @click="resetFrom()">重置</el-button> </div> <script> export default { data() { return { ruleForm: { email: '', password: '' }, rules: { email: [{ required: true, message: '请输入邮箱' }], password: [{ required: true, message: '请输入密码' }] } } }, methods: { resetFrom() { this.$refs.ruleForm.resetFields() }, login() { //表单预校验 this.$refs.ruleForm.validate(async valid => { if (!valid) return //发送请求 const { data } = await this.$http.post('/admin/login',this.ruleForm) if (data.status !== 200) { return this.$message({ type: 'error', message: data.msg }) } this.$message({ type: 'success', message: `登陆成功,欢迎您${data.user.name}` }) window.sessionStorage.setItem('token', data.token) window.sessionStorage.setItem('username', data.user.name) this.$router.push('/admin/welcome') }) } } } </script>
-
后台服务器
-
在
app.js
文件中创建好服务器后,我们需要设置跨域请求-
// 设置跨域和相应数据格式 app.all('*', function (req, res, next) { res.header('Access-Control-Allow-Origin', 'http://localhost:8081') res.setHeader("Access-Control-Allow-Credentials", "true") res.header('Access-Control-Allow-Headers', 'X-Requested-With, mytoken') res.header('Access-Control-Allow-Headers', 'X-Requested-With, Authorization') res.setHeader('Content-Type', 'application/json;charset=utf-8') res.header('Access-Control-Allow-Headers', 'Content-Type,Content-Length, Authorization, Accept,X-Requested-With') res.header('Access-Control-Allow-Methods', 'PUT,POST,GET,DELETE,OPTIONS') res.header('X-Powered-By', ' 3.2.1') // if (req.method == 'OPTIONS') res.send(200) // /*让options请求快速返回*/ else next() })
-
-
在与
app.js
文件平级的目录下我们可以创建一个router
文件夹,来管理所有的路由文件 -
在
app.js
全局挂载express-session
插件-
npm install express-session //安装
-
// 引入express-session模块 const session = require('express-session') // 只要http请求有insurance就会创建session app.use(session({ store: new FileStore(),//数据持久化方式,这里表示本地文件存储 //加密方式 secret: 'secret key', resave: true, rolling: true, saveUninitialized: false, //过期时间,单位毫秒 cookie: { maxAge: 3000 * 60 * 60 } }))
-
-
在
router
文件夹下创建一个login.js
文件,用来管理与登陆相关的路由及代码-
引入
express
模块后,用express.Router()
方法来创建模块化路由对象-
const express = require(‘express’)
const login = express.Router()
-
-
拦截路由请求
-
login.post(’/login’,(req,res)=>{})
-
-
使用第三方模块
bodyParse
,可以解析表单请求对象-
npm install bodyParse //安装
-
在
app.js
中全局挂载 -
// 拦截post请求,挂载req.body
app.use(bodyParser.urlencoded({ extended: false }))
// 如果不设置bodyParser.json()就接收不到axios发送的json数据请求
app.use(bodyParser.json())
-
-
// 引入express插件 const express = require('express') let login = express() // 引入密码解密插件 const bcrypt = require('bcrypt') // 引入数据库User const { User } = require('../../db/index') // 拦截来自‘/login’的post请求 login.post('/login', async (req, res) => { const userInfo = req.body // console.log(userInfo); const user = await User.findOne({ email: userInfo.email }) // console.log(user); if (!user) { res.send({ msg: '用户邮箱或密码错误', status: 400 }) return } else { // console.log(await (bcrypt.compare(userInfo.password, user.password))); if (! await (bcrypt.compare(userInfo.password, user.password))) { return res.send({ msg: '用户名或密码错误', status: 400 }) } else { // 返回用户信息,状态码,sessionID用来做数据保护,下次请求没有这个ID请求不成功 // console.log(req.session); // console.log(req.sessionID); req.session.flag = true res.send({ user, status: 200, token: req.sessionID }) } } }) //导出这个函数 module.exports = { login }
-
在
app.js
文件中设置中间件拦截请求-
const {login} =require('./router/login') app.use('/login',login)
-
-