创建NodeAPI接口
1、新建文件夹app_server,在根目录中打开终端输入:npm i ,生成pack.json文件;
2、下载express,终端输入:npm i express@4.17.1(指定版本);
一、创建服务器app.js;
// 导入 express 模块
const express = require('express')
// 创建服务器的实例
const app = express()
// 启动服务器
app.listen(3007,(req, res) => {
console.log('api server running at http://127.0.0.1:3007');
})
4、配置cors跨域
①、在根目录下执行命令按
照:npm i cors@2.8.5;
②、导入模块配置解析表单的中间件;
// 导入cors并配置cros中间件
const cors = require('cors')
app.use(cors())
// 配置解析application x-www-form-urlencoded 模式的表单数据 的中间件
app.use(express.urlencoded({ extended: false}))
二、创建路由
1、在根目录下新建router文件夹,用来存放路由模块;新建router_hander文件夹存放路由处理函数模块;
2、创建路由user.js;
// 导入 express 模块
const express = require('express')
// 创建路由对象
const userRouter = express.Router()
// 挂载路由 注册新用户
userRouter.post('/reguser', (req, res) => {
res.send('reguser ok')
})
// 挂载路由 登陆
userRouter.post('/login',(req, res) => {
res.send('login ok')
})
// 共享出去router模块
module.exports = userRouter
3、在服务器中导入并注册路由模块
// 导入并注册路由模块
const userRouter = require('./router/user')
app.use('/api',userRouter)
4、抽离用户路由模块的处理函数,在router_hander文件夹中新建user.js,存放路由模块的处理函数;
// 注册新用户的处理函数
exports.regUser = (req, res) => {
res.send('reguser ok')
}
// 登陆的处理函数
exports.login = (req, res) => {
res.send('login ok')
}
在路由模块router文件夹下的user.js,导入router_hander/user.js,使用里面共享出来的模块;
// 导入用户路由处理函数模块
const user_hander = require('../router_hander/user')
// 挂载路由 注册新用户
userRouter.post('/reguser', user_hander.regUser)
// 挂载路由 登陆
userRouter.post('/login',user_hander.login)
5、注册新用户——创建数据库表格
6、注册新用户——按照与配置mysql模块;
在根目录下打开终端输入:npm i mysql@2.18.1;
在文件夹db下的index.js中导入mysql模块并创建数据库连接对象;
// 导入mysql模块
const mysql = require('mysql')
// 创建数据库连接对象
const db = mysql.createPool({
host: '127.0.0.1',
user: 'root',
password: 'hoshi1234',
datebase: 'my_dv_01'
})
// 向外共享 数据库的连接对象
module.exports = db
7、注册新用户——检测用户名是否合法/用户名是否被占用/使用bcryptjs给用户密码加密/封装res.cc()函数;
在router_hander中的user.js的注册新用户函数中,判断req.body的属性是否为false;
导入db数据库操作模块,定义SQL语句查询username,当它length大于0则代表被占用;
——————————————
在app.js中,封装res.cc()函数作为全局中间件,用来调用res.send()函数像客户端处理失败的结果
// 优化res.send()代码
// 在处理函数中需要多次调用res.send()向客户端响应处理失败的结果,为了简化代码可以手动分装一个res.cc()函数
// 在路由之前,声明一个全局中间件,为res对象挂载一个res.cc()函数
app.use(function(req, res, next){
res.cc = function(err, status = 1) {
res.send({
status,
// 判断err是否为错误对象(构造函数中的实例对象) true 则返回err.message,false则说明它是个字符串,直接返回err
message: err instanceof Error ? err.message: err,
})
}
next()
})
优化表单数据验证
使用第三方包来数据验证;
1、安装joi:为表单中携带的数据项,定义验证规则,根目录下终端执行命令:npm i joi;
2、安装:@escook/express-joi中间件,来实现自动对表单数据进行验证;
3、在scheme文件夹下新建user.js,用来存放一些用户验证规则;
// 用户信息验证规则模块
// 导入joi第三方模块
const joi = require('joi')
// 定义用户名和密码的验证规则
// string() 值必须是字符串
// alphanum() 值只能包含a-zA-Z的字符串
// min(1).max(10) 最大长度, 最小长度
// required() 值是必填项
// pattern() 值必须符合正则表达式
const username = joi.string().alphanum().min(1).max(10).required()
const password = joi.string().pattern(/^[\S]{6,12}$/).required()
// 定义验证注册和登录表单数据的规则对象 再对外共享
exports.reg_login_schema = {
body: {
username,
password
}
}
在router文件夹下的user.js中,导入@escook/express-joi中间件和需要验证规则的对象,在路由器中url后插入中间件;
// 导入验证表单数据的中间件
const expressJoi = require('@escook/express-joi')
// 导入需要验证规则的对象
const { reg_login_schema } = require('../schema/user')
// 创建路由对象
const userRouter = express.Router()
// 导入用户路由处理函数模块
const user_hander = require('../router_hander/user')
// 挂载路由 注册新用户
// 在路由中,声明局部中间件,对当前请求中携带的数据进行验证
// 数据验证通过后,会把这次请求流转给后面的路由处理函数
// 数据验证失败后,终止后续代码的执行,并跑出一个全局Error错误,进入全局错误级别中间件中进行处理
userRouter.post('/reguser', expressJoi(reg_login_schema), user_hander.regUser)
如果验证失败则调用错误中间件,在app.js中导入joi模块;
// 导入 joi 模块
const joi = require('joi')
// 导入并注册路由模块
const userRouter = require('./router/user')
app.use('/api',userRouter)
//定义错误级别的中间件
app.use((err, reg, res, next) => {
// 注意 此处一定要加return 终止 不然会连续调用两次res.send()程序,会报错
if(err instanceof joi.ValidationError) return res.cc(err)
// 未知的错误
res.cc(err)
})
router_hander文件夹下的user.js中,处理函数的路由代码如下:
// 注册新用户的处理函数
exports.regUser = (req, res) => {
// 检测用户名是否合法
const userinfo = req.body
// 对表单中的数据进行合法性的校验
// 当userinfo.username 或者 userinfo.username = false
// 没有对应数据或者属性时则显示false
// if(!userinfo.username || !userinfo.username) {
// return res.send({
// status: 1,
// message: '用户用户名或密码不合法!'
// })
// }
// 检测用户名是否被占用
// 1.定义SQL语句,检测用户名是否被占用
const sqlStr = 'select * from my_dv_01.dv_users where username=?'
// 2.执行SQL语句
db.query(sqlStr, userinfo.username, (err, results) => {
if(err) {
// return res.send({
// status: 1,
// message: err.message
// })
return res.cc(err)
}
// 当userinfo.username的长度大于0,说明当前用户名已存在
if(results.length > 0) {
// return res.send({
// status: 1,
// message: '用户名被占用,请选择其他用户名!'
// })
return res.cc('用户名被占用,请选择其他用户名!')
}
// TODO:使用bcryptjs对用户密码进行加密处理
// 1.下载包 npm i bcryptjs@2.4.3
// 2.导入包
// 3.调用bcrypt.hashSync()的方法对密码进行加密,10能提高密码安全 性,把加密后的结果再赋值给userinfo.password
console.log(userinfo);
// password: '000000'
userinfo.password = bcrypt.hashSync(userinfo.password, 10)
console.log(userinfo);
// password: '$2a$10$H75J0rWlVeiQh4yhQfsrWumWmcEEQgHZ9HvMMXqvL.n.ZpXP8Tj1y'
// 插入新用户
// 1.定义SQL语句
const sql = 'insert into my_dv_01.dv_users set ?'
// 2.执行SQL语句
db.query(sql,{username: userinfo.username, password: userinfo.password}, (err, results) => {
if(err)
// res.send({
// status: 1,
// message: err.message
// })
return res.cc(err)
if(results.affectedRows !== 1)
// res.send({
// status: 1,
// message: '插入新用户失败,请稍后再试!'
// })
return res.cc('插入新用户失败,请稍后再试!')
// 注册用户成功
// res.send({
// status: 0,
// message: '插入新用户成功!'
// })
res.cc('插入新用户成功!',0)
})
})
}
用户登录的接口
1、检测表单数据是否合法