当前位置: 首页 > news >正文

网站设计时图片怎么做武汉百度推广代运营

网站设计时图片怎么做,武汉百度推广代运营,网站安全狗服务名,修改网站照片需要怎么做代码下载 初始化 新建 apiServer 文件夹作为项目根目录,并在项目根目录中运行如下的命令,初始化包管理配置文件: npm init -y运行如下的命令,安装 express、cors: npm i express cors在项目根目录中新建 app.js 作为整个项目的入口文件&a…

代码下载

初始化

新建 apiServer 文件夹作为项目根目录,并在项目根目录中运行如下的命令,初始化包管理配置文件:

npm init -y

运行如下的命令,安装 express、cors:

npm i express cors

在项目根目录中新建 app.js 作为整个项目的入口文件,配置 cors 跨域中间件、解析表单数据的中间件,并启动服务器:

// 导入 express 模块
const express = require('express');
// 创建 express 的服务器实例
const app = express();// 配置跨域中间件
const cors = require('cors');
app.use(cors());// 配置解析 application/x-www-form-urlencoded 格式的表单数据的中间件
app.use(express.urlencoded({ extended: false }));// 指定端口号并启动web服务器
app.listen('80', function() {console.log('server running at http://127.0.0.1:80');
});

因为在处理函数中,需要多次调用 res.send() 向客户端响应 处理失败 的结果,为了简化代码, 可以手动封装一个 res.cc() 函数。在 app.js 中所有路由之前,声明一个全局中间件,为 res 对象挂载一个 函数 :

// 在 路由 之前自定义中间件,处理错误的响应数据
app.use(function(req, res, next) {// status 默认值1,表示失败,0表示成功// err 可能是错误对象,也可能是错误描述字符串res.cc = function(err, status = 1) {res.send({status: status,message: err instanceof Error ? err.message : err});};next();
});
  1. 在项目根目录中,新建 router 文件夹,用来存放所有的 路由 模块,路由模块中,只存放客户端的请求与处理函数之间的映射关系
  2. 在项目根目录中,新建 routerHandler 文件夹,用来存放所有的 路由处理函数模块 路由处理函数模块中,专门负责存放每个路由对应的处理函数
  3. 在项目根目录中,新建 db 文件夹,用来存放所有的 数据库 模块
  4. 在项目根目录中,新建 middleware 文件夹,用来存放所有的 自定义中间件 模块

登录注册

新建 users 表,在 my_db_01 数据库中,新建 ev_users 表如下:
请添加图片描述

安装并配置 mysql 模块,需要安装并配置 mysql 这个第三方模块,来连接和操作 MySQL 数据库,运行如下命令,安装 mysql 模块:

npm i mysql

在项目根目录中 db 文件夹新建 index.js 文件,在此自定义模块中创建数据库的连接对象:

const mysql = require('mysql');
const db = mysql.createPool({host: 'localhost',port: '3306',user: 'root',password: 'admin123',database: 'my_db_01'
});module.exports = db;

初始化用户路由模块

在 router 文件夹中,新建 user.js 文件,作为用户的路由模块,并初始化代码如下:

const express = require('express') // 创建路由对象
const router = express.Router()
// 注册新用户
router.post('/signin', (req, res) => {res.send('signin OK')
})
// 登录
router.post('/login', (req, res) => {res.send('login OK')
})
// 将路由对象共享出去 module.exports = router

在 app.js 中,导入并使用 用户路由模块 :

// 配置路由
const user = require('./router/user');
app.use('/api', user);

抽离用户路由模块中的处理函数

为了保证 路由模块 的纯粹性,所有的 路由处理函数,必须抽离到对应的 路由处理函数模块中。

在 /routerHandler/user.js 中,使用 exports 对象,分别向外共享如下两个 路由处理函数:

/**
* 在这里定义和用户相关的路由处理函数,供 /router/user.js 模块进行调用 */// 注册用户的处理函数 
exports.signin = (req, res) => {res.send('signin OK')
}// 登录的处理函数
exports.login = (req, res) => {res.send('login OK')
}

将 /router/user.js 中的代码修改为如下结构:

const express = require('express');
const router = express.Router();
const handler = require('../routerHandler/user');// 注册
router.post('/signin', handler.signin);// 登录
router.post('/login', handler.login);module.exports = router;

joi 表单数据验证

表单验证的原则:前端验证为辅,后端验证为主,后端 永远不要相信 前端提交过来的 任何内容。

在实际开发中,前后端都需要对表单的数据进行合法性的验证,而且, 后端做为数据合法性验证的最后 一个关口 ,在拦截非法数据方面,起到了至关重要的作用。

单纯的使用 if…else… 的形式对数据合法性进行验证,效率低下、出错率高、维护性差。因此, 推荐使用 第三方数据验证模块 ,来降低出错率、提高验证的效率与可维护性, 让后端程序员把更多的精力放在核心业务逻辑的处理上。

安装 joi 包,为表单中携带的每个数据项,定义验证规则:

npm install joi

在 /middleware/expressJoi.js 中,使用 joi 对象,定义并向外共享表单数据验证中间件:

const joi = require('joi');const expressJoi = function (schemas, options = { strict: false }) {// 自定义校验选项// strict 自定义属性,默认不开启严格模式,会过滤掉那些未定义的参数项//        如果用户指定了 strict 的值为 true,则开启严格模式,此时不会过滤掉那些未定义的参数项if (!options.strict) {// allowUnknown 允许提交未定义的参数项// stripUnknown 过滤掉那些未定义的参数项options = { allowUnknown: true, stripUnknown: true, ...options }}// 从 options 配置对象中,删除自定义的 strict 属性delete options.strict// TODO: 用户指定了什么 schema,就应该校验什么样的数据return function (req, res, next) {['body', 'query', 'params'].forEach(key => {// 如果当前循环的这一项 schema 没有提供,则不执行对应的校验if (!schemas[key]) return// 执行校验const schema = joi.object(schemas[key])const { error, value } = schema.validate(req[key], options)if (error) {console.log('---------------');// 校验失败throw error} else {// 校验成功,把校验的结果重新赋值到 req 对应的 key 上req[key] = value}})// 校验通过next()}
}module.exports = expressJoi

新建 /schema/user.js 用户信息验证规则模块,并初始化代码如下:

// @hapi/joi 包,为表单中携带的每个数据项,定义验证规则
const joi = require('joi');// * string() 值必须是字符串
// * alphanum() 值只能是包含 a-zA-Z0-9 的字符串 * min(length) 最小长度
// * max(length) 最大长度
// * required() 值是必填项,不能为 undefined
// * pattern(正则表达式) 值必须符合正则表达式的规则
const username = joi.string().alphanum().min(2).max(20).required();
const password = joi.string().required().pattern(/^[\S]{6,16}$/);exports.schema = {user: {body: {username,password}}
}

修改 /router/user.js 中的代码如下:

// 导入验证表单数据的中间件
const expressJoi = require('../middleware/expressJoi');
// 导入需要的验证规则对象
const { schema } = require('../schema/user');// 为 注册新用户 配置表单验证中间件
// 在注册新用户的路由中,声明局部中间件,对当前请求中携带的数据进行验证
//      数据验证通过后,会把这次请求流转给后面的路由处理函数
//      数据验证失败后,终止后续代码的执行,并抛出一个全局的 Error 错误,进入全局错误级别中间件中进行 处理
router.post('/signin', expressJoi(schema.user), handler.signin);// 登录
router.post('/login', expressJoi(schema.user), handler.login);

在 app.js 的全局错误级别中间件中,捕获验证失败的错误,并把验证失败的结果响应给客户端:

// 配置 错误处理 中间件
const joi = require('joi');
app.use(function(err, req, res, next) {// console.log(err);if (err instanceof joi.ValidationError) {// 处理数据校验错误} else {// 处理其他未知错误}return res.cc(err);
});

加密处理

为了保证密码的安全性,不建议在数据库以 明文 的形式保存用户密码,推荐对密码进行 加密存储。使用 对用户密码进行加密,优点:

  • 加密之后的密码, 无法被逆向破解
  • 同一明文密码多次加密,得到的 加密结果各不相同 ,保证了安全性

运行如下命令,安装 bcryptjs:

npm i bcryptjs

调用 bcrypt.hashSync(明文密码, 随机盐的长度) 方法,对用户的密码进行加密处理:

const bcrypt = require('bcryptjs');
// 对用户的密码,进行 bcrype 加密,返回值是加密之后的密码字符串
userinfo.password = bcrypt.hashSync(userinfo.password, 10);

调用 bcrypt.compareSync(用户提交的密码, 数据库中的密码) 方法比较密码是 否一致,返回值是布尔值(true 一致、false 不一致):

// 拿着用户输入的密码,和数据库中存储的密码进行对比
const compareResult = bcrypt.compareSync(userinfo.password, results[0].password);// 如果对比的结果等于 false, 则证明用户输入的密码错误 
if (!compareResult) {console.log('密码错误!');
}

注册

  1. 检测表单数据是否合法
  2. 检测用户名是否被占用
  3. 对密码进行加密处理
  4. 插入新用户

新建 /middleware/constValue.js 常量数据模块,并初始化代码如下:

// sql 语句
// 查找用户名
const selectUN = `select * from users where username = ?`;
// 插入用户
const insertUser = `insert into users set ?`;module.exports = {selectUN,insertUser
}

修改 /routerHandler/user.js 中的代码,实现最终完整的登录逻辑,如下:

const bcrypt = require('bcryptjs');
const constValue = require('../middleware/constValue');
const signin = (req, res) => {const info = req.body;// 数据校验交给 expressJoi 中间件处理// if (info.username && info.password) {db.query(constValue.selectUN, info.username, function(err, result) {if (err) {res.cc(err);} else if (result.length > 0) {res.cc('用户名被占用,请更换其他用户名!');} else {// 调用 bcrypt.hashSync(明文密码, 随机盐的长度) 方法,对用户的密码进行加密处理info.password = bcrypt.hashSync(info.password, 10);db.query(constValue.insertUser, {username: info.username, password: info.password}, function(err, result) {if (err) {res.cc(err);} else if (result.affectedRows === 1) {res.cc('注册成功!', 0);} else {res.cc('注册失败,请稍后重试!');}});}});// } else {//     res.cc('用户名或密码不能为空!');// }
};

登录

  1. 检测表单数据是否合法
  2. 根据用户名查询用户的数据
  3. 判断用户输入的密码是否正确
  4. 生成 JWT 的 Token 字符串

在 /middleware/constValue.js 定义并导出查询用户数据的 SQL 语句以及 JWT 秘钥、加密算法、无权限表达式:

// 查找用户信息
const selectInfo = `select id, username, nickname, email, user_pic from users where id = ?`;
// JWT 秘钥
const jwtSecretKey = 'JWTSecretKeyabcABC123!@#JWTSecretKey';
// JWT 加密算法
const jwtAlgorithms = 'HS256';
// JWT 无需权限的接口 表达式
const jwtUnlessPath = /^\/api\//;

运行如下的命令,安装生成 Token 字符串的包、解析 Token 的中间件的包:

npm i jsonwebtoke express-jwt

核心注意点: 在生成 Token 字符串的时候,一定要剔除 密码 和 头像 的值 通过 ES6 的高级语法,快速剔除 密码 和 头像 的值,将用户信息对象加密成 Token 字符串:

// 通过 ES6 的高级语法,快速剔除用户敏感信息后的数据作为 token 的加密数据
const user = { ...result[0], password: '', user_pic: '' }
// token 有效期为 10 天
const token = jwt.sign(user, constValue.jwtSecretKey, { expiresIn: '10d' });

在 app.js 中注册路由之前,配置解析 Token 的中间件:

// 配置 解析 Token 的中间件
var { expressjwt } = require('express-jwt');
const constValue = require('./middleware/constValue');
app.use(expressjwt({secret: constValue.jwtSecretKey, algorithms: [constValue.jwtAlgorithms]
}).unless({path: [constValue.jwtUnlessPath]
}));

在 app.js 中的 错误级别中间件里面,捕获并处理 Token 认证失败后的错误:

app.use(function(err, req, res, next) {// console.log(err);if (err instanceof joi.ValidationError) {// 处理数据校验错误} else if (err.name === 'UnauthorizedError') {// 处理身份认证失败的错误return res.cc('身份验证失败!');} else {// 处理其他未知错误}return res.cc(err);
});

修改 /routerHandler/user.js 中的代码,实现最终完整的登录逻辑,如下:

const jwt = require('jsonwebtoken');
const expressJwt = require('express-jwt');
const { use } = require('../router/user');
const login = (req, res) => {const info = req.body;// 查询 username 是否存在db.query(constValue.selectUN, info.username, function(err, result) {if (err) {res.cc(err);} else if (result.length === 1) {// 判断密码是否正确if (bcrypt.compareSync(info.password, result[0].password)) {// 剔除用户敏感信息后的数据作为 token 的加密数据const user = { ...result[0], password: '', user_pic: '' }console.log(user);const token = jwt.sign(user, constValue.jwtSecretKey, { expiresIn: '10d' });res.send({status: 0,token: 'Bearer ' + token,message: '登录成功!'});} else {res.cc('密码错误!');}} else {res.cc('登录失败!');}});
};

个人中心

获取用户的基本信息

  1. 初始化 路由 模块
  2. 初始化 路由处理函数 模块
  3. 获取用户的基本信息

创建 /router/userinfo.js 路由模块,并初始化如下的代码结构:

const express = require('express');
const router = express.Router();
const handler = require('../routerHandler/userinfo');// 获取用户信息
router.get('/userinfo', handler.userinfo);module.exports = router;

在 app.js 中导入并使用个人中心的路由模块:

const userinfo = require('./router/userinfo');
app.use('/my', userinfo);

在 /middleware/constValue.js 定义并导出查询用户信息的 SQL 语句:

// 查找用户信息
const selectInfo = `select id, username, nickname, email, user_pic from users where id = ?`;

创建 /routerHandler/userinfo.js 文件,实现最终完整的逻辑,如下:

const db = require('../db/index');
const constValue = require('../middleware/constValue');const userinfo = function(req, res) {console.log(req.auth);db.query(constValue.selectInfo, req.auth.id, function(err, result) {if (err) {res.cc(err);} else if (result.length === 1) {res.send({status: 0,data: result[0],message: '用户信息获取成功!'});} else {res.cc('用户信息获取失败!');}});
};module.exports = {userinfo
};

更新用户的基本信息

  1. 定义路由和处理函数
  2. 验证表单数据
  3. 实现更新用户基本信息的功能

具体实现见代码……

重置密码

  1. 定义路由和处理函数
  2. 验证表单数据
  3. 实现重置密码的功能

在 /schema/user.js 验证规则模块中,定义 newPassword 的验证规则并使用 exports 向外共享如下的验证规则对象:

const password = joi.string().required().pattern(/^[\S]{6,16}$/);
// 1. joi.ref('oldPassword') 表示 newPassword 的值必须和 oldPassword 的值保持一致
// 2. joi.not(joi.ref('oldPwd')) 表示 newPwd 的值不能等于 oldPwd 的值
// 3. .concat() 用于合并 joi.not(joi.ref('oldPwd')) 和 password 这两条验证规则
const newPassword = joi.not(joi.ref('oldPassword')).concat(password);exports.schema = {updatePassword: {body: {oldPassword: password,newPassword}}
}

其他具体实现见代码……

更新用户头像

  1. 定义路由和处理函数
  2. 验证表单数据
  3. 实现更新用户头像的功能

在 /schema/user.js 验证规则模块中,定义 user_pic 的验证规则并使用 exports 向外共享如下的验证规则对象:

// dataUri() 指的是如下格式的字符串数据:
// data:image/png;base64,VE9PTUFOWVNFQ1JFVFM=
const user_pic = joi.string().dataUri().required();exports.schema = {updateAvatar: {body: {user_pic}}
}

在 /router/userinfo.js 模块中,导入需要的验证规则对象, 修改 更新用户头像 的路由:

const expressJoi = require('../middleware/expressJoi');
const { schema } = require('../schema/user');
// 更换头像
router.post('/updateAvatar', expressJoi(schema.updateAvatar), handler.updateAvatar);

在 /middleware/constValue.js 定义并导出 更新用户头像 的 SQL 语句:

// 修改头像
const updateAvatar = `update users set user_pic = ? where id = ?`;

处理 /routerHandler/userinfo.js 中的代码,实现最终完整的登录逻辑,如下:

// 更换头像
const updateAvatar = (req, res) => {console.log('------------');console.log(req.body);db.query(constValue.updateAvatar, [req.body.user_pic, req.auth.id], (err, result) => {if (err) {res.cc(err);} else if (result.affectedRows === 1) {res.cc('更换头像成功!', 0);} else {res.cc('更换头像失败!');}})
}

文章分类管理

具体实现见代码……

文章管理

新建 articles 表如下:
请添加图片描述

发布新文章

  1. 初始化路由模块
  2. 初始化路由处理函数模块
  3. 使用 multer 解析表单数据
  4. 验证表单数据
  5. 实现发布文章的功能

创建 /routerHandler/article.js 路由处理函数模块,并初始化如下的代码结构:

// 发布新文章的处理函数 
exports.addArticle = (req, res) => {res.send('ok')
}

创建 /router/article.js 路由模块,并初始化如下的代码结构:

// 导入 express
const express = require('express') 
// 创建路由对象
const router = express.Router()// 导入文章的路由处理函数模块
const handler = require('../routerHandler/article');// 发布新文章
routor.post('/addArticle', handler.addArticle);// 向外共享路由对象 
module.exports = router

在 app.js 中导入并使用文章的路由模块:

const article = require('./router/article');
app.use('/my', article);
使用 multer 解析表单数据

注意: 使用 express.urlencoded() 中间件无法解析 multipart/form-data 格式的请求体 数据。

推荐使用 multer 来解析 multipart/form-data 格式的表单数据。运行如下的终端命令,在项目中安装 multer :

npm i multer

在 /router/article.js 模块中导入并配置 multer :

// 导入解析 formdata 格式表单数据的包 
const multer = require('multer') 
// 导入处理路径的核心模块
const path = require('path')
// 创建 multer 的实例对象,通过 dest 属性指定文件的存放路径
const upload = multer({ dest: path.join(__dirname, '../uploads') })// 发布新文章的路由
// upload.single() 是一个局部生效的中间件,用来解析 FormData 格式的表单数据
// 将文件类型的数据,解析并挂载到 req.file 属性中
// 将文本类型的数据,解析并挂载到 req.body 属性中
routor.post('/addArticle', uploads.single('cover_img'), handler.addArticle);
实现发布文章的功能

通过 express-joi 自动验证 req.body 中的文本数据;通过 if 判断手动验证 req.file 中的 文件数据。

在 /schema/user.js 验证规则模块中,定义数据验证规则并使用 exports 向外共享如下的 验证规则对象:

const id = joi.number().integer().min(1).required();
const title = joi.string().required();
const content = joi.string().required().allow('');
const state = joi.string().valid('已发布', '草稿').required();exports.schema = {addArticle: {body: {title,content,cate_id: id,state}}
}

在 /router/article.js 模块中,导入需要的验证规则对象,并在路由中使用。

在 /middleware/constValue.js 定义并导出 发布文章 的 SQL 语句:

// 插入文章
const insertArticle = `insert into articles set ?`;

修改 /routerHandler/article.js 中的代码,实现最终完整的登录逻辑,如下:

const addArticle = (req, res) => {console.log(req.body);console.log(req.file);if (req.file && req.file.fieldname === 'cover_img') {const article = {...req.body,// 文章封面在服务器端的存放路径cover_img: `/uploads/${req.file.filename}`,pub_date: new Date(),author_id: req.auth.id};db.query(constValue.insertArticle, article, (err, result) => {if (err) {res.cc(err);} else if (result.affectedRows === 1) {res.cc('文章添加成功!', 0);} else {res.cc('文章添加失败!');}});} else {res.cc('cover_img 是必选参数!');}
}
http://www.ritt.cn/news/3197.html

相关文章:

  • 年轻人适合开什么公司济南百度seo
  • 做网站去青鸟学什么专业自媒体怎么做
  • 台州seo网站排名优化百度官方网平台
  • 上海站有云网络科技有限公司我对网络营销的理解
  • 请多记几个本站域名防止抖音seo排名软件
  • 没有做网站经验可以学seo吗新站seo快速排名 排名
  • 农业网站建设模板下载企业网站优化解决方案
  • 通过网站做国际贸易的成本提高工作效率总结心得
  • 网站建网站建设企业电话线上推广平台都有哪些
  • 网站备案后怎么建网站店铺推广方法
  • 网站ftp查询网站如何赚钱
  • 银川网站制作权威发布
  • 网站建设需要注意哪些关键细节被国家禁止访问的网站怎么打开
  • 泰州企业建站系统下列哪些店铺适合交换友情链接
  • 别人用我的备案信息做网站国际局势最新消息今天
  • 对网站建设的考核机制百度推广在哪里能看到
  • 杭州百度推广网站建设太原seo快速排名
  • 一般vs做的网站的总体框架聊城seo整站优化报价
  • 旧安卓手机做网站网络营销师报考条件
  • 咖啡网站建设设计规划书武汉网站快速排名提升
  • 上海网站建设费用公关公司是干嘛的
  • wordpress商城文章seo关键词优化培训
  • 电商网站开发多少钱友链交换不限内容
  • 新疆巴州建设局网站seo精准培训课程
  • 上海住房和城乡建设部网站首页全国各城市疫情高峰感染高峰进度
  • 武汉大型网站建设北京seo培训
  • 如何申请com网站公众号推广方案
  • 合肥网站建设yjhlw高级搜索引擎技巧
  • 北京网站建设公司分享网站改版注意事项网站模板商城
  • 卢湾企业微信网站制作国内新闻摘抄2022年