- 数据库配置
- 项目简介
- 登录功能
- 登录拦截
- 添加用户
- 展示用户列表
- 用户头像上传
- 用户列表展示
- 用户信息修改
- 删除用户
- 批量删除用户
- 修改密码
- 添加分类
- 分类数据展示
- 分类数据修改
- 分类数据删除
- 添加文章
- 文章列表数据展示
- 文章数据列表筛选
- 文章编辑
- 文章删除
- 评论列表展示
- 评论审核
- 评论删除
- 图片轮播数据添加
- 轮播图数据展示
- 图片轮播数据删除
- 网站设置
- 显示网站设置数据
- 展示登录用户信息
- 轮播图数据展示
- 热门推荐recommend.js
- 搜索
- 阿里百秀接口文档
- 实践知识点汇总
数据库配置
数据库配置,为alibaixiu数据库创建普通账号
(1)
mongo
进入mongodb数据库操作环境(2)
use admin
切换到admin数据库(3)
db.auth('root', 'root')
登录admin数据库(4)
use alibaixiu
切换到alibaixiu数据库(5)
db.createUser({user: 'sparkparis', pwd: '123', roles: ['readWrite']})
创建账号(6)
exit
退出mongodb数据库操作环境将阿里百秀项目文件夹复制到硬盘中(服务器端程序)
在app.js中配置数据库账号密码
使用命令行工具进行到项目根目录中
使用
npm install
命令安装项目所需的第三方模块将阿里百秀静态页面复制到public文件夹中
在命令行工具中输入node app.js开启项目
项目简介
阿里百秀,内容管理系统,分为内容管理和内容展示两大核心功能。
1. 功能模块
1.1 内容管理
模块 | 功能 |
---|---|
用户 | 登录、退出、用户增删改查 |
文章 | 文章管理 |
分类 | 分类管理 |
评论 | 评论管理 |
网站设置 | 关键字、描述、网站logo、轮播图 |
1.2 内容展示
模块 | 功能 |
---|---|
首页 | 导航、文章数据展示 |
列表页 | 根据分类显示文章列表 |
详情页 | 文章详情数据展示、实现评论功能 |
2. 开发模式
2.1 前后端混合开发模式
所有HTML代码和数据在服务器端拼接好,一次性将所有内容发送到客户端,浏览器执行代码,将内容呈现给用户
问题:
- 前后端开发人员对互相的代码都不是别熟悉,混合开发两者在处理互相的代码时非常困难
- 在开发的过程中难免会出现代码互相覆盖,导致工作量倍增
2.2 前后端分离开发模式
好处:职责、分工明确,独立开发,互不影响。
3. 项目架构
系统分层 | 使用技术 |
---|---|
数据层 | mongoDB |
服务层 | node.js (express) |
客户端 | art-template、jQuery、font-awesome、swipe |
4. 项目运行环境搭建
- 安装node.js软件并测试其是否安装成功
- win + R 开启windows系统中的运行程序,在运行程序中输入powershell回车,打开命令行程序
- 输入
node -v
命令查看node.js的版本,在命令行程序中输出了版本号没有报错即说明安装成功
- 安装mongodb、mongodb-compass软件
- 将阿里百秀项目文件夹复制到硬盘中(服务器端程序)
- 在命令行工具中进入到项目根目录中
- 按住shift键,点击鼠标右键,选择在此处打开powershell窗口
- 使用
npm install
命令安装项目所需依赖文件 - 将阿里百秀静态页面复制到public文件夹中
- 在命令行工具中输入node app.js开启项目
登录功能
- 为登录按钮添加点击事件
- 获取用户在文本框中输入的用户名和密码
- 验证用户是否输入了用户名和密码,如果没有输入,阻止程序向下执行,提示用户输入用户名和密码
- 调用实现登录功能的接口,登录成功,跳转到数据管理的首页,登录失败,提示用户名或密码错误
登录拦截
- 使用script标签加载服务器端提供的接口地址
- 判断isLogin变量的值,如果值为false,跳转到登录页面
- 在登录拦截功能中,不能采用异步的方式,必须采用同步方式进行拦截,所有也不能通过ajax请求来进行请求的发送,这里需要在admin/index页面中进行页面的用户登录状态的判断
添加用户
- 为添加用户功能的每一个表单项添加name属性,且name属性值需要和接口文档中要求的参数名称保持一致
- 为表单绑定提交事件,在事件处理函数中阻止表单默认提交的行为
- 在事件处理函数中获取到用户在表单中输入的内容
- 调用添加用户接口,将获取到的内容通过接口发送给服务器端,操作成功刷新页面,操作失败给出用户提示
- 刷新页面:location.reload()
- form.serilize()方法序列化提交的表单参数
- 取消表单的默认行为return false
- 模块化管理,用户操作都放在js中(public文件夹下的js文件)
展示用户列表
- 向服务器端发送Ajax请求,索要用户列表数据
- 第二步,使用模板引擎将数据和html模板进行拼接
- 第三步就是将拼接好的内容展示在页面中
用户头像上传
- 为文件选择控件添加onchange事件,在事件处理函数中获取到用户选择到的文件
- 创建formData对象用于实现图片文件上传
- 调用图片文件上传接口,实现图片上传
- 在添加新用户表单中新增一个隐藏域,将图片地址存储在隐藏域中
- 文件上传中获取上传的文件调用的属性是dom对象.files,这里的files属性是dom对象的,不是jquery对对象的
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$('#avatar').on('change', function () {
// 通过FormData的方式上传二进制文件
var formData = new FormData();
// 添加上传文件
// console.log(this);这里的this指的是dom对象
// console.log($(this)),$(this)表示的是jquery对象
// files属性是dom对象的属性
formData.append('avatar', this.files[0]);
// 发送ajax请求
$.ajax({
type: 'post',
url: '/upload',
data: formData,
// 告诉ajax不要解析请求参数,上传的是二进制文件
processData: false,
// FormData中设置了文件上传的方式,这里不需要在设置文件上传的类型
contentType: false,
success: function (response) {
// 这里返回的是文件的上传到服务器端的地址response[0].avatar
// console.log(response[0].avatar);
// 实现头像预览功能
$('#preview').attr('src', response[0].avatar);
// 将图片地址隐藏在隐藏域中
$('#hiddenAvatar').val(response[0].avatar);
}
})
}) - 注意在使用用jquery时注意使用方法和属性是jquery对象还是dom对象
用户列表展示
- 在页面加载时向服务器端发送Ajax请求,索要用户列表数据
- 使用模板引擎将数据和html模板进行拼接
- 将拼接好的内容展示在页面中
用户信息修改
- 通过事件委托的形式为编辑按钮点击添加事件(ajax是异步执行的,不能确定什么时候返回,这里通过事件委托的方式将点击事件委托给父元素)
- 在事件处理函数中获取到当前点击用户的id值
- 根据用户id获取用户的详细信息,并且通过模板引擎将用户的详细信息渲染到左侧的表单中((通过自定义属性data-in保存当前点击的id))
- 为修改按钮添加点击事件,在事件处理函数中获取到用户在表单中输入的内容,调用修改用户信息接口实现用户信息修改功能。
- 涉及到的知识点
- 事件委派on()方法,
- 获取当前点击的id通过data-in自定义属性,为当前点击按钮添加类名
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16- 通过on('submit')方法提交表单信息
// 通过事件委派的方式编辑用户信息(为编辑标签添加类名和data-in自定义属性)
$('#userBox').on('click', '.edit', function () {
// 获取edit类名所在的data-in属性来获取当前点击的id
var id = $(this).attr('data-in');
// 根据id查询当前用户(发送ajax请求)(restful风格的api)
$.ajax({
type: 'get',
url: '/users/' + id,
success: function (response) {
var html = template('modifyTel', response);
// 将修改的页面加载到页面中
$('#modifyBox').html(html);
}
})
})删除用户
- 为删除按钮添加点击事件
- 确认用户是否要进行删除操作
- 获取到当前被点击用户的id
- 调用删除用户接口根据id删除用户,如果删除成功,刷新当前页面,让页面显示最新的内容
- 通过事件委派的方式删除用户
- 删除多个用户通过-进行连接eg:/users/:id-id-id
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15// 通过事件委派的方式删除用户(添加类名delete和data-in自定义属性来获取删除id)
$('#userBox').on('click', '.delete', function () {
// 确认是否删除
if (confirm('你确认删除该用户?')) {
var id = $(this).attr('data-in');
// 发送ajax请求
$.ajax({
type: 'delete',
url: '/users/' + id,
success: function () {
location.reload();
}
})
}
})批量删除用户
- 管理复选框的选中状态
- 当全选按钮被选中时,所有用户要被选中,当全选按钮取消选中时,所有用户要被取消选中
- 当用户前面的复选框按钮状态被改变时,要检查是否有用户处于未选中状态,如果有,取消全选按钮的选中状态,如果没有,就意味着所有用户都处于选中状态,此时将全选按钮设置为选中状态
- 管理批量删除按钮的状态
- 当全选按钮被选中时,显示批量删除按钮,当全选按钮被取消选中时,隐藏批量删除按钮
- 当用户前面的复选框按钮状态改变时,检查所有用户的选中状态,如果有用户被选中,显示批量删除按钮,如果所有用户都没有处于选中状态,隐藏批量删除按钮
- 实现批量删除用户功能
- 批量删除按钮添加点击事件,在点击事件处理函数中,将所有被选中的用户id执行存储在一个数组中
- 调用用删除用户接口,实现删除用户功能
- 知识点
- jquery对象获取固有属性prop(),自定义属性attr()方法
- $.each((index,ele)=>{})方法中的ele===this是dom对象,调用jquery方法需转化为jquery对象$(ele)
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61// 删除多个用户
// (1)设置全选全不选的同步状态
var selectAll = $('#selectAll');
var deleteMany = $('#deleteMany');
// 为全选按钮添加改变事件
selectAll.on('change', function () {
// 获取当前按钮的选中状态
var status = $(this).prop('checked');
// 批量删除按钮显示与隐藏
if (status) {
// 显示批量删除按钮
deleteMany.show();
} else {
// 隐藏批量删除按钮
deleteMany.hide()
}
// 查找所有的用户并设置选中状态(通过事件委派的方式)
$('#userBox').find('input').prop('checked', status);
})
// 当用户当前的状态发生变化时
$('#userBox').on('change', '.userStatus', function () {
// 思路:判断当前input中选中的个数个当前用户的length是否相等
var inputs = $('#userBox').find('input');
if (inputs.length == inputs.filter(':checked').length) {
selectAll.prop('checked', true);
} else {
selectAll.prop('checked', false);
}
// 批量删除按钮显示与隐藏
if (inputs.filter(':checked').length > 0) {
// 显示批量删除按钮
deleteMany.show();
} else {
// 隐藏批量删除按钮
deleteMany.hide()
}
})
// 删除按钮添加点击事件,删除多个用户通过restful api的风格,这里采用的是/users/:id-id-id,将删除的id保存在数组中方便连接,在input中添加data-in自定义属性获取选中的id
deleteMany.on('click', function () {
var ids = [];
//获取选中用户
var checkedUser = $('#userBox').find('input').filter(':checked');
// 循环将每个input属性中的data-in值保存在数组中
checkedUser.each((index, ele) => {
// 注意这里ele是dom对象===this,这里需使用jquery对象获取对应的属性值
var id = $(ele).attr('data-in');
ids.push(id);
});
// console.log(ids)
if (confirm('确认删除以下选中用户?')) {
// 发送ajax请求
$.ajax({
type: 'delete',
url: '/users/' + ids.join('-'),
success: function () {
location.reload();
}
})
}
})修改密码
- 为修改密码表单中的每一个表单项添加name属性,name属性的值要和接口中的参数名称保持一致
- 为修改密码表单添加表单提交事件,在事件处理函数中,阻止表单的默认提交行为
- 获取到用户在表单中输入的内容
- 调用修改密码接口,实现密码修改功能,如果密码修改成功,跳转到登录页面,让用户重新登录
- 知识点
- express-formidable可以解析的内容类型有:application/x-www-form-urlencoded, application/json, and multipart/form-data
1
2
3
4
5
6
7
8
9
10
11// 处理文件上传
const formidableMiddleware = require('express-formidable');
// 处理post参数
app.use(formidableMiddleware({
// 文件上传目录
uploadDir: path.join(__dirname, 'public', 'uploads'),
// 最大上传文件为2M
maxFileSize: 2 * 1024 * 1024,
// 保留文件扩展名
keepExtensions: true
}));
- express-formidable可以解析的内容类型有:application/x-www-form-urlencoded, application/json, and multipart/form-data
添加分类
- 为表单中的每一个表单项添加name属性,name属性的值要和接口文档中要求的参数名称保持一致
- 为表单添加表单提交事件,在事件处理函数中,阻止表单提交的默认行为
- 获取到用户在表单中输入的内容
- 调用分类添加接口,实现添加分类功能
分类数据展示
- 向服务器端发送Ajax请求,索要分类页面数据
- 使用模板引擎将服务器端返回的数据和HTML模板进行拼接(需要将id值存在在value中)
- 将拼接好的内容展示在页面中
分类数据修改
- 通过事件委托为编辑按钮添加点击事件,在事件处理函数中获取到要修改的分类数据id
- 根据id调用接口,获取分类数据的详细信息
- 利用模板引擎将分类数据和HTML字符进行拼接,拼接完成以后将内容渲染到页面中
- 为修改按钮添加点击事件,在事件处理函数中获取到管理员在表单中输入的内容
- 调用修改分类数据接口,实现分类数据修改功能。
分类数据删除
- 通过事件委托的方式为删除按钮添加点击事件,在点击事件处理函数弹出删除确认框
- 在用户点击了确认删除后,获取要删除的分类数据的id
- 调用删除分类数据接口,实现删除分类数据功能,如果分类删除成功,刷新页面
添加文章
- 获取文章分类数据,并将数据显示在所属分类的下拉列表中供管理员选择
- 实现文章封面图片的上传,并将上传后的图片地址保存在一个隐藏域中
- 为添加文章表单中的每一个表单项添加name属性,并且name属性值要和接口中要求的参数名称保持一致
- 为添加文章表单绑定表单提交事件,在事件处理函数中阻止表单默认提交的行为
- 获取到管理员在表单中输入的内容
- 向服务器端发送添加文章的请求,实现文章添加功能,文章添加成功以后要跳转到文章列表页面
文章列表数据展示
- 在页面一上来的时候向服务器端发送请求索要文章列表数据
- 通过模板引擎将文章列表数据和HTML进行拼接,拼接完成以后将内容显示在页面中
- 根据分页数据实现列表数据分页功能
- 分页实现
1
2
3
4
5
6
7
8
9
10
11
12<!-- 分页模板 -->
<script type="text/html" id="pageTpl">
{{if page > 1}}
<li><a href="javascript;;" onclick='changePage({{page-1}})'>上一页</a></li>
{{/if}}
{{each display}}
<li><a href="javascript:;" onclick='changePage({{$value}})'>{{$value}}</a></li>
{{/each}}
{{if page < pages}}
<li><a href="javascript:;" onclick='changePage({{page+1}})'>下一页</a></li>
{{/if}}
</script>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
31
32
33
34
35
36
37
38
39
40
41
42
43
44// 页面一开始就加载文章列表
$.ajax({
type: 'get',
url: '/posts',
success: function (response) {
console.log(response)
// 绑定模板
var html = template('articleListTpl', response);
// 添加到页面
$('#articleBox').html(html);
// 绑定分页模板
console.log(response);
var page = template('pageTpl', response);
console.log(page)
$('#pageBox').html(page);
}
})
//取消页面选择中a的默认行为,并为a添加点击事件发送ajax请求,传递参数page
function changePage(page) {
$.ajax({
type: 'get',
url: '/posts',
// 传递当前显示的页码
data: { page: page },
success: function (response) {
console.log(response)
// 绑定模板
var html = template('articleListTpl', response);
// 添加到页面
$('#articleBox').html(html);
// 绑定分页模板
var page = template('pageTpl', response);
$('#pageBox').html(page);
}
})
}
// 对日期格式格式化
function dateFormat(date) {
// 将字符串日期转化为Date对象
var date = new Date(date);
// 月是从0开始的需要加1
return date.getFullYear() + '-' + (date.getMonth() + 1) + '-' + date.getDate();
}
文章数据列表筛选
- 向服务器端发送请求,索要文章分类数据,并将数据显示在所属分类的下来列表中
- 为筛选按钮添加点击事件,在事件处理函数中获取到用户选择到的内容
- 向服务器端发送请求,索要管理员要求的文章列表数据,并将数据显示在页面中
文章编辑
- 为编辑按钮添加链接,并将文章id作为链接的查询参数传递到文章编辑页面
- 在文章编辑页面获取地址栏中的id参数
- 根据id获取文章详细信息,并将文章信息显示在文章编辑表单中
- 为修改文章表单绑定表单提交事件,在事件处理函数中阻止表单默认提交的行为
- 获取到用户在表单中输入的内容
- 向服务器端发送请求,实现修改文章信息功能,如果文章信息修改成功,跳转到文章列表页面
- 通过事件委托为删除按钮添加点击事件,在事件处理函数中弹出一个删除确认框,跟管理员确认删除操作
- 在事件处理函数中获取要要删除的文章的id
- 发送Ajax请求,执行删除操作,删除操作成功,刷新页面
评论列表展示
- 向服务器端发送请求,获取评论列表数据
- 使用模板引擎将评论列表数据和HTML模板进行拼接,拼接完成以后再将内容展示在页面中
- 根据分页数据实现分页功能
评论审核
- 根据当前评论的状态更改审核按钮中的文字。如果当前评论是未审核状态,按钮中显示批准,如果当前评论是已审核状态,按钮中显示驳回
- 通过事件委托的方式为审核按钮添加点击事件,在事件处理函数中获取到当前评论的状态
- 向服务器端发送请求,告诉服务器端评论要更改为什么状态,如果修改成功,刷新页面,让页面中显示最新的数据
评论删除
- 通过事件委托的方式为删除按钮添加点击事件,在事件处理函数中弹出删除确认框
- 获取到管理员要删除的评论id值
- 向服务器端发送请求,执行删除评论操作,评论如果删除成功,刷新页面
图片轮播数据添加
- 实现图片上传功能,并且将上传后的图片地址保存在一个隐藏域中
- 为图片轮播表单中的每一个表单项添加name属性,name属性的值要和接口中要求的参数名称保持一致
- 为图片轮播表单绑定表单提交事件,在事件处理函数中阻止表单默认提交的行为
- 获取到管理员在表单中输入的内容
- 向服务器端发送请求,实现图片轮播数据添加功能,如果数据添加成功,刷新页面
轮播图数据展示
- 向服务器端发送请求索要图片轮播列表数据
- 使用模板引擎将图片轮播列表数据和HTML模板进行拼接,拼接完成以后将内容展示在页面中
图片轮播数据删除
- 通过事件委托的方式为删除按钮添加点击事件
- 在事件处理函数中弹出删除确认框
- 获取到要删除的轮播图数据的id
- 向服务器端发送请求,执行删除操作,删除操作成功,刷新页面
网站设置
- 实现网站logo图片的上传,并且将上传后的图片地址保存在一个隐藏域中
- 为表单中的每一个表单项添加name属性,name属性的值要和接口文档中要求的参数名称保持一致
- 为表单绑定提交事件,在事件处理函数中阻止表单默认提交的行为
- 获取到管理员在表单中输入的内容
- 向服务器端发送请求,实现网站设置数据的添加功能
显示网站设置数据
- 向服务器端发送请求,获取网站设置数据
- 判断服务器端返回的数据是否为真,如果为真,将数据展示在表单中
展示登录用户信息
- 根据userId变量的值,向服务器端获取当前登录用户的信息
- 将用户信息显示在页面的左侧
1
2
3
4
5
6
7
8
9
10
11
12common.js
// 显示用户的信息(通过在index.html中调用接口/login/status 获取返回值isLogin和userId的全局变量[可直接使用])
// 根据id获取用户的详细信息
$.ajax({
type: 'get',
url: '/users/' + userId,
success: function (response) {
// 将查询到的信息显示在页面中
$('.profile .avatar').attr('src', response.avatar);
$('.profile .name').html(response.nickName)
}
})
轮播图数据展示
- 向服务器端发送请求索要轮播图数据
- 使用模板引擎将数据和HTML字符串进行拼接,将拼接好的内容显示在页面中
- 将原有的实现轮播图效果的JavaScript代码挪到ajax方法的success函数的最后面
热门推荐recommend.js
向服务器端发送请求,索要热门推荐数据
使用模板引擎将数据和html模板进行拼接,将拼接好的内容显示在页面中
1
2
3var str = '<div>{{name}}</div>';
var obj = {name: '张三'}
var html = template.render(str, obj);
- 遇到的问题:公共的模板部分怎么引用到html页面中
- 解决方案:
- 公共部分的模板写在抽离出来的js文件中,通过模板字符串的方式获取,并通过template.render(str,{})的方式进行渲染
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22// 索要热门推荐数据
$.ajax({
type: 'get',
url: '/posts/recommend',
success: function (response) {
// 将公共模板写在js文件中通过字符串进行拼接
var str = `
{{each data}}
<li>
<a href="detail.html?{{$value._id}}">
<img src="{{$value.thumbnail}}">
<span>{{$value.title}}</span>
</a>
</li>
{{/each}}
`;
// 渲染模板
var html = template.render(str, { data: response });
// 添加到页面中
$('#hotBox').html(html)
}
})搜索
- 公共部分的模板写在抽离出来的js文件中,通过模板字符串的方式获取,并通过template.render(str,{})的方式进行渲染
- 为搜索表单绑定表单提交事件
- 在事件处理函数中阻止表单默认提交行为并且获取到用户输入的搜索关键字
- 跳转到搜索结果页面并且将用户输入的搜索关键字传递到搜索结果页面
- 在搜索结果页面中,从地址栏的查询参数中获取到用户输入的关键字
- 根据用户输入的搜索关键字调用搜索接口,当服务器端返回数据以后,将搜索结果数据和HTML模板进行拼接,最终将拼接好的内容展示在页面中
- 公共展示部分(搜索,最新评论和随机推荐)的js放在public.js文件中编写,并将模板写在js文件中
- 网站搜索功能是公共部分,获取搜索框并绑定提交事件(注意搜索结果展示页面和list.html一样复制一份作为搜索页面展示)
阿里百秀接口文档
基础URL:http://localhost:3000
1. 用户管理
1.1 创建用户
请求地址 | 请求方式 |
---|---|
/users | POST |
参数名称 | 是否必选 | 参数说明 |
---|---|---|
nickName | 是 | 用户昵称 |
是 | 邮件地址 | |
password | 是 | 登录密码 |
role | 是 | 角色 [admin 超级管理员] [normal 普通用户] |
avatar | 否 | 头像 |
status | 是 | 状态 [0 未激活] [1 激活] |
1 | { |
1.2 用户登录
请求地址 | 请求方式 |
---|---|
/login | POST |
参数名称 | 是否必选 | 参数说明 |
---|---|---|
是 | 邮箱地址 | |
password | 是 | 登录密码 |
1 | { |
1.3 退出登录
请求地址 | 请求方式 |
---|---|
/logout | POST |
1 | { |
1.4 操作用户
1.4.1 获取用户登录状态
请求地址 | 请求方式 |
---|---|
/login/status | GET |
1 | var isLogin = true; |
1.4.2 获取用户列表
请求地址 | 请求方式 |
---|---|
/users | GET |
1 | [ |
1.4.3 根据 id 查询用户
请求地址 | 请求方式 |
---|---|
/users/:id | GET |
1 | { |
1.4.4 根据 id 修改用户
请求地址 | 请求方式 |
---|---|
/users/:id | PUT |
参数名称 | 是否必选 | 参数说明 |
---|---|---|
nickName | 是 | 用户昵称 |
status | 否 | 用户状态 |
role | 否 | 用户角色 |
avatar | 否 | 用户头像 |
1 | { |
1.4.5 根据 id 删除用户
请求地址 | 请求方式 | 说明 |
---|---|---|
/users/:id | DELETE | 批量删除,多个id用-隔开,例如:/users/:id-id-id |
1 | { |
1 | [ |
1.4.6 修改用户密码
请求地址 | 请求方式 |
---|---|
/users/password | PUT |
参数名称 | 是否必选 | 参数说明 |
---|---|---|
userPass | 是 | 原密码 |
newPass | 是 | 新密码 |
confirmPass | 是 | 确认密码 |
1 | { |
2. 分类管理
2.1 添加分类
请求地址 | 请求方式 |
---|---|
/categories | POST |
参数名称 | 是否必选 | 参数说明 |
---|---|---|
title | 是 | 分类名称 |
className | 是 | 分类图标类名 |
1 | { |
2.2 查询分类
2.2.1 根据 id 查询分类
请求地址 | 请求方式 |
---|---|
/categories/:id | GET |
1 | { |
2.2.2 查询分类列表
请求地址 | 请求方式 |
---|---|
/categories | GET |
1 | [ |
2.2.3 查询分类数量
请求地址 | 请求方式 |
---|---|
/categories/count | GET |
1 | { |
2.5 根据 id 修改分类
请求地址 | 请求方式 |
---|---|
/categories/:id | PUT |
参数名称 | 是否必选 | 参数说明 |
---|---|---|
title | 否 | 分类名称 |
className | 否 | 分类图标类名 |
1 | { |
2.6 根据 id 删除分类
请求地址 | 请求方式 | 说明 |
---|---|---|
/categories/:id | DELETE | 批量删除,多个id用-隔开,例如:/categories/:id-id-id |
1 | { |
1 | [ |
3. 文章管理
3.1 创建文章
请求地址 | 请求方式 |
---|---|
/posts | POST |
参数名称 | 是否必选 | 参数说明 |
---|---|---|
title | 是 | 文章标题 |
state | 是 | 文章状态 [0 草稿] [1 发布] |
content | 是 | 文章内容 |
category | 是 | 文章所属分类 |
thumbnail | 否 | 文章缩略图 |
createAt | 是 | 文章发布时间 |
1 | { |
3.2 查询文章
3.2.1 根据 id 获取文章
请求地址 | 请求方式 |
---|---|
/posts/:id | GET |
1 | { |
3.2.2 查询文章列表
请求地址 | 请求方式 |
---|---|
/posts | GET |
参数名称 | 是否必选 | 参数说明 |
---|---|---|
category | 否 | 文章所属分类 |
state | 否 | 文章状态 [0 草稿] [1 发布] |
page | 否 | 文章页码 |
1 | { |
3.2.3 根据分类获取文章列表
请求地址 | 请求方式 |
---|---|
/posts/category/:id | GET |
1 | [ |
3.2.4 查询文章数量
请求地址 | 请求方式 |
---|---|
/posts/count | GET |
1 | { |
3.2.5 获取最新发布文章
请求地址 | 请求方式 |
---|---|
/posts/lasted | GET |
1 | [ |
3.2.6 获取热门推荐
请求地址 | 请求方式 |
---|---|
/posts/recommend | GET |
1 | [ |
3.2.7 获取随机推荐
请求地址 | 请求方式 |
---|---|
/posts/random | GET |
1 | [ |
3.3 根据 id 修改文章
请求地址 | 请求方式 |
---|---|
/posts/:id | PUT |
参数名称 | 是否必选 | 参数说明 |
---|---|---|
title | 否 | 文章标题 |
state | 否 | 文章状态 [0 草稿] [1 发布] |
content | 否 | 文章内容 |
category | 否 | 文章所属分类 |
thumbnail | 否 | 文章缩略图 |
1 | { |
3.4 根据 id 删除文章
请求地址 | 请求方式 |
---|---|
/posts/:id | DELETE |
1 | { |
3.5 文章点赞
请求地址 | 请求方式 |
---|---|
/posts/fabulous/:id | POST |
1 | { |
3.6 文章搜索
请求地址 | 请求方式 |
---|---|
/posts/search/:key | GET |
1 | [ |
4. 评论管理
4.1 创建评论
请求地址 | 请求方式 |
---|---|
/comments | POST |
参数名称 | 是否必选 | 参数说明 |
---|---|---|
content | 是 | 评论内容 |
post | 是 | 评论文章id |
state | 是 | 评论状态 |
1 | { |
4.2 获取评论列表
请求地址 | 请求方式 |
---|---|
/comments | GET |
参数名称 | 是否必选 | 参数说明 |
---|---|---|
page | 否 | 页码 |
1 | { |
4.3 更改评论状态
请求地址 | 请求方式 |
---|---|
/comments/:id | PUT |
参数名称 | 是否必选 | 参数说明 |
---|---|---|
state | 是 | 0或1 |
1 | { |
4.4 查询评论数量
请求地址 | 请求方式 |
---|---|
/comments/count | GET |
1 | { |
4.5 获取最新评论
请求地址 | 请求方式 |
---|---|
/comments/lasted | GET |
1 | [ |
4.6 根据 id 删除评论
请求地址 | 请求方式 |
---|---|
/comments/:id | DELETE |
1 | { |
5. 网站设置
5.1 添加轮播图片
请求地址 | 请求方式 |
---|---|
/slides | POST |
参数名称 | 是否必选 | 参数说明 |
---|---|---|
title | 是 | 轮播图标题 |
image | 是 | 轮播图片 |
link | 否 | 图片链接 |
1 | { |
5.2 获取轮播图列表
请求地址 | 请求方式 |
---|---|
/slides | GET |
1 | [ |
5.3 删除轮播图片
请求地址 | 请求方式 |
---|---|
/slides/:id | DELETE |
1 | { |
5.4 网站配置
请求地址 | 请求方式 |
---|---|
/settings | POST |
参数名称 | 是否必选 | 参数说明 |
---|---|---|
title | 是 | 站点名称 |
comment | 是 | 是否开启评论功能 |
review | 是 | 评论必须经过人工审核 |
logo | 否 | 网站图标 |
1 | { |
5.5 获取网站配置
请求地址 | 请求方式 |
---|---|
/settings | GET |
1 | { |
6. 其他功能
图片文件上传
请求地址 | 请求方式 |
---|---|
/upload | POST |
参数名称 | 是否必选 | 参数说明 |
---|---|---|
avatar | 是 | 图片文件 |
1 | [ |
- 文件上传功能中:是先将图片保存在FormData对象中;上传到服务器端,获取服务器端的存储地址;
将服务器端返回的存储地址设置为隐藏域中的value值,隐藏域中的name属性设置为上传文件的name属性1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21$('#feature').on('change', function () {
// 通过formData上传文件
var formData = new FormData();
// 获取当前文件
var file = this.files[0]
formData.append('cover', file);
// 发送ajax请求获取服务器短地址
$.ajax({
type: 'post',
url: '/upload',
data: formData,
// 不要让浏览器进行解析
processData: false,
// 不要设置类型,formdata对象中已经设置了类型
contentType: false,
success: function (response) {
// 将服务器端返回的地址保存在隐藏域中
$('#thumbnai').val(response[0].cover)
}
})
})实践知识点汇总
- 页面跳转的两种方式
- 服务器端:res.render()
- 客户端:location.href = ‘页面跳转地址’
- Lodash工具的使用,对对象进行操作
- _.pick(object, [props]):创建一个从 object 中选中的属性的对象
- 超链接a标签中,取消默认行为href=’javascript:;’
- 发送ajax请求是异步操作,必须取消表单,超链接等的默认行为
- 表单:return false
- a标签:href=’javascript:;’
- 在进行数据分页的时候可以对a链接添加点击事件进行页面的加载
1
<a href="javascript:;" onclick='changePage({{page-1}})'>上一页</a>
- 获取地址栏中的参数:location.search属性方法
- 在模板字符串中修改操作时显示日期需要提交日期的年月日才能正常显示createAt.split(‘T’)[0]
- 动态添加的选项进行点击事件一般委托给固定的父元素添加提交事件,在on()方法中的第二个参数指定当前点击选项的类名或者id名称
- 动态加载的删除操作,通过事件委派方式让固定的父元素添加点击事件,通过on()中删除按钮的类名或者id名称获取当前点击的选项,通过将删除的id存在删除按钮的自定义属性中(data-名称)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18html文件
<a href="javascript:;" class="btn btn-danger btn-xs delete" data-id={{$value._id}}>删除</a>
js代码
$('#articleBox').on('click', '.delete', function () {
var id = $(this).attr('data-id');
// 确认是否删除
if (confirm('确认删除所选文章吗?')) {
// 发送ajax请求删除
$.ajax({
type: 'delete',
url: '/posts/' + id,
success: function () {
// 删除成功刷新页面
location.reload();
}
})
}
}) - 公共模板(在多个网页中使用)抽离js文件,将模板写在js文件中,通过template.render(‘模板字符串’,}{})来渲染页面
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15// 将公共模板写在js文件中通过字符串进行拼接
var str = `
{{each data}}
<li>
<a href="detail.html?{{$value._id}}">
<img src="{{$value.thumbnail}}">
<span>{{$value.title}}</span>
</a>
</li>
{{/each}}
`;
// 渲染模板
var html = template.render(str, { data: response });
// 添加到页面中
$('#hotBox').html(html) - 对于公共模板分别引入不同的页面中即可
- 在网页缩小时会出现顶部分类目录
- 文章点赞
1
2
3
4
5
6
7
8
9
10
11
12// 通过事件委托的方式(目的获取当前文章的id)实现点赞功能,点赞成功
$('#articleBox').on('click', '#like', function () {
// 发送点赞请求
$.ajax({
type: 'post',
url: '/posts/fabulous/' + postId,
success: function () {
// 点赞成功提示用户即可
alert('点赞成功,感谢你的支持');
}
})
}) - 搜索功能中正则表达式的匹配问题(待解决)
1
text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
- 添加评论功能需要的实现点:
- 用户登录身份的判断
- 文章详情页面获取网站配置信息
- 提交评论
本文链接: https://sparkparis.github.io/2020/04/27/Ajax-project/
版权声明: 本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。转载请注明出处!