image-CloudDisk 是一个 Vue 练手项目,由个人开发者负责维护,旨在向前端初学者和 Vue 使用者提供真实的项目开发经验。
在客户端,我们提供了完整的源代码,各位可以结合示例代码,开发自己的客户端。
在服务器端,我们提供大量的真实 API,并附带翔实的接口文档。
iamge-CloudDisk 是一个照片和视频的云盘管理程序,通过学习开发这一前端项目,我们相信你会对如下内容有深入理解:
欢迎向仓库 issue 你的想法、建议和代码
如果你愿意参与到这个项目中,我们非常欢迎
扫码联系项目维护者:
在知乎联系我:
在微信联系我:
请项目维护者喝杯咖啡
在这里,我们提供一个基础的网络请求地址,接下来的所有 url 都以此地址为 baseURL
baseURL: "https://alonepluto.info/api/cloud/v1"
当然,这是一个绕不开的问题,跨域可以在后端解决,也可以在前端解决。
在1.1.7 版本之前,项目的跨域是在后端解决,之后为了加强对 Vue 的练习,我们果断把这个问题抛给了前端
你可以通过配置 vue.config.js 中的 devServer.proxy 来解决跨域问题
//vue.config.js
module.exports = {
// 开发环境代理服务器
devServer: {
proxy: {
"/api": {
target: "https://alonepluto.info/api/cloud/v1",
changeOrigin: true,
pathRewrite: {
"^/api": ""
}
}
}
}
}
为了防止接口被恶意调用,节约服务器资源,调用所有接口均需向服务器传递 SecretKey(/test 接口除外),你需要在发送网络请求时,设置自定义请求头 SecretKey,下面以 axios 为例:
axios({
method:'get'
url:'/login',
//设置请求头,建议使用拦截器自动添加请求头
headers:{
SecretKey:'e8feJD8fje9jfkellppzw80eYmTTs'
}
})
项目封装了 axios,并针对开发环境配置了环境变量,你可以用最新的 SecretKey 替换项目根目录下.env.development 文件中的 VUE_APP_SECRET_KEY,以轻松完成对 SecretKey 的引入
//.env.development
NODE_ENV = development
VUE_APP_BASE_URL = /api
VUE_APP_SECRET_KEY = XG9RVD8F9EGH //替换
你可以通过知乎或者微信向项目维护者索要最新的 SecretKey
前后端通信通过 token 保持登录状态
登录成功后,服务器端会向前端返回一个 token 值,后续前端发起网络请求时,均需向服务器传递 token(/test 接口除外),以验证身份。无 token 或 token 过期,则网络请求失败。
服务器端拦截网络请求的请求头,通过 Authorization 字段获取 token 值,因此,前端发起网络请求时,需要设置请求头,下面以 axios 为例:
axios({
method:'post'
url:'/edit',
//设置请求头,建议使用拦截器自动添加请求头
headers:{
Authorization:'gkrlkoxg5ffFE89vjke77HJK'
}
})
在客户端,点击一个图片或视频链接,可直接下载资源,而不是在一个新窗口打开资源,这极大简化了开发者从服务器下载静态资源的步骤,开发者无需再编写额外的业务代码
//客户端
//将资源url赋值给a标签,点击后可直接下载
const a = document.createElement("a")
a.setAttribute("href", this.file.file_src)
a.click()
//服务器端
//响应类型为通用文件类型
ctx.set("content-type", "application/octet-stream")
//要求浏览器下载文件,而不是在浏览器中进行展示
ctx.set("Content-Disposition", `attachment;filename=${ctx.url.split("/").pop()}`)
实现这一功能的关键在于服务器端设置了特殊的响应头,它强制要求浏览器直接下载资源,而不需要打开它
如果你不了解 nodejs 可忽略这部分内容,你只需要知道,请求服务器端静态资源,会直接下载该资源
服务器暴露了一个网络测试接口,接口地址:'/test',请求方法:'get',如果请求 test 接口返回如下内容,说明服务器工作正常
{
code:825,
message:'网络通信正常'
}
参数名 | 说明 | 值类型 | 是否必选 | 示例 |
---|---|---|---|---|
user_name | 用户名 | String | 是 | user_name:'admin' |
user_password | 用户密码 | String | 是 | user_password:'123456' |
返回值
{
//服务器自定义状态码
code:802,
//响应结果
message:'登录成功',
//响应数据
data:{
//用户详细信息
user:{},
//令牌,用于后续请求服务器数据时验证身份
token:'e8Vufe8JFKLEV9989je8Vhkf8v',
//用户收藏夹列表
folders:[]
}
}
说明:用于新用户注册
接口地址:'/login/signin'
请求方法:'post'
参数:
参数名 | 说明 | 值类型 | 是否必选 | 示例 |
---|---|---|---|---|
user_name | 用户名 | String | 是 | - |
user_password | 用户密码 | String | 是 | - |
user_question | 用户密保问题 | String | 否 | - |
user_answer | 密保问题答案 | String | 否 | - |
mock | 服务器虚拟 10 天的数据,建议使用 | String | 否 | mock:'mock' |
返回值
{
//服务器自定义状态码
code:820,
//响应结果
message:'注册成功',
}
提示:
说明:用于新用户注册时,请求服务器验证用户名是否已存在
接口地址:'/login/checkname'
请求方法:'post'
参数:
参数名 | 说明 | 值类型 | 是否必选 | 示例 |
---|---|---|---|---|
user_name | 用户注册名 | String | 是 | - |
返回值:
{
//服务器自定义状态码
code:810,
//响应结果
message:'验证成功,用户名可用',
}
提示:
为了良好的用户体验,前端最好在发起注册请求前,先行验证用户输入的注册名是否在服务器已存在
你可以在用户名输入框失去焦点时请求此接口
说明:用于用户忘记登录密码时,重置密码
接口地址:'/login/resetpassword'
请求方法:'post'
参数:
参数名 | 说明 | 值类型 | 是否必选 | 示例 |
---|---|---|---|---|
user_name | 用户名 | String | 是 | - |
user_password | 用户新密码 | String | 是 | - |
返回值:
{
//服务器自定义状态码
code:808,
//响应结果
message:'操作成功',
}
说明:获取由服务器提供的密保问题列表,当然,你也可以自己设置一个密保问题,不过这不是一个好的选择
接口地址:'/login/getquestions',
请求方法:'get'
参数:无
返回值:
{
//服务器自定义状态码
code:800,
//响应结果
message:'查询成功,返回结果',
//密保问题列表
data:[ "你最想去的星球?", "你最喜欢的一本书?", "你最讨厌的水果?", "你最难忘的人?" ]
}
说明:获取用户预先设置的密保问题和答案,用以重置密码时验证用户身份
接口地址:'/login/getuserquestion'
请求方法:'get',
参数:
参数名 | 说明 | 值类型 | 是否必选 | 示例 |
---|---|---|---|---|
user_name | 用户名 | String | 是 | - |
返回值:
{
//服务器自定义状态码
code:800,
//响应结果
message:'查询成功,返回结果',
//密保问题列表
data:{
user_question:'你最讨厌的水果?',
user_answer:'榴莲'
}
}
说明:请求时间戳功能的数据
接口地址:'/data/getTimelineDataLimit'
请求方法:'get'
参数:
参数名 | 说明 | 值类型 | 是否必选 | 示例 |
---|---|---|---|---|
page | 请求第几页数据 | Number | 是 | 0 |
limit | 每页显示几条数据 | Number | 是 |
返回值:
{
code:800,
message:'查询成功,返回结果',
data:[
[{...},{...},{...}],
[{...}],
[{...},{...}],
...
]
}
提示:
返回的数据为一个二维数组,每个数组中储存相同日期上传的所有图片和视频,数组元素按时间降序排列
说明:以时间戳的方法获取全部数据
接口地址:'/data/getTimelineData'
请求方法:'get'
参数:无
返回值:
{
code:800,
message:'查询成功,返回结果',
data:[
[{...},{...},{...}],
[{...}],
[{...},{...}],
...
]
}
说明:一次性请求用户上传的所有图片格式的数据
接口地址:'/data/getImageData'
请求方法:'get'
参数:无
返回值:
{
code:800,
message:'查询成功,返回结果',
data:[
{...},
{...},
...
]
}
提示:
返回的是一个一维数组,所有的数据按时间降序排列
说明:一次性请求用户上传的所有视频格式的数据
接口地址:'/data/getvideoData'
请求方法:'get'
参数:无
返回值:
{
code:800,
message:'查询成功,返回结果',
data:[
{...},
{...},
...
]
}
提示:
返回的是一个一维数组,所有的数据按时间降序排列
说明:灵活地按照资源类型分页请求数据
接口地址:'/data/getDataLimit'
请求方法:'get',
参数:
参数名 | 说明 | 值类型 | 是否必选 | 示例 |
---|---|---|---|---|
type | 资源类型 | String | 否 | 默认值 all,即同时请求图片和视频,可选值为 image 和 video |
page | 分页 | Number | 是 | - |
limit | 每页数据量 | Number | 是 | - |
说明:请求特定日期的数据
接口地址:'/data/getDateData'
请求方法:'get'
参数:
参数名 | 说明 | 值类型 | 是否必选 | 示例 |
---|---|---|---|---|
date_list | 日期数组 | Array | 是 | ['2021/06/02','2021/06/03'] |
返回值
{
code:800,
message:'查询成功,返回结果',
data:[
{'2021/06/02':[{...},{...}]},
{'2021/06/03':[{...}]}
]
}
提示:
响应结果为数组,数组元素为以查询日期为键的键值对
说明:获取用户上传的图片的数量、视频的数量、上传文件的总大小
接口地址:'/data/getCounter'
请求方法:'get'
参数:无
返回值:
{
code:800,
message:'查询成功,返回结果',
data:{
image:20,
video:15,
size:9866234
}
}
说明:
接口地址:'/data/foundfolder'
请求方法:'post'
参数:
参数名 | 说明 | 值类型 | 是否必选 | 示例 |
---|---|---|---|---|
folder_name | 收藏夹名称 | String | 是 | - |
返回值:
{
code:808,
message:'操作成功'
}
说明:删除用户收藏夹
接口地址:'/data/deleteFolder'
请求方法:'delete'
参数:
参数名 | 说明 | 值类型 | 是否必选 | 示例 |
---|---|---|---|---|
folder_name | 收藏夹名称 | String | 是 | - |
返回值:
{
code:808,
message:'操作成功'
}
说明:将图片或视频添加到用户已创建的收藏夹
接口地址:'/data/addFolder'
请求方法:'post'
参数:
参数名 | 说明 | 值类型 | 是否必选 | 示例 |
---|---|---|---|---|
file_id | 文件 ID | String | 是 | - |
file_folder | 添加到哪个收藏夹 | String | 是 | - |
返回值:
{
code:808,
message:'操作成功'
}
说明:
接口地址:'/data/deleteFile'
请求方法:'delete'
参数:
参数名 | 说明 | 值类型 | 是否必选 | 示例 |
---|---|---|---|---|
file_id | 文件 ID | String | 是 | - |
返回值:
{
code:808,
message:'操作成功'
}
说明:删除单个文件
接口地址:'/data/renameFile'
请求方法:'put'
参数:
参数名 | 说明 | 值类型 | 是否必选 | 示例 |
---|---|---|---|---|
file_id | 文件 ID | String | 是 | - |
file_name | 文件新名称 | String | 是 | - |
返回值:
{
code:808,
message:'操作成功'
}
说明:批量删除文件
接口地址:'/data/bulkDelete'
请求方法:'delete'
参数:
参数名 | 说明 | 值类型 | 是否必选 | 示例 |
---|---|---|---|---|
file_list | 要删除的文件 ID 数组 | Array | 是 | - |
返回值:
{
code:814,
message:'批量删除成功',
//响应数据为成功删除的文件ID列表
data:[
'1658938495',
'1690697063'
]
}
说明:统计同一个收藏夹下的图片和视频的数量
接口地址:'/data/getFolderData'
请求方法:'get'
参数:
参数名 | 说明 | 值类型 | 是否必选 | 示例 |
---|---|---|---|---|
folder | 收藏夹名称 | String | 是 | - |
返回值:
{
code:800,
message:'查询成功,返回结果',
//返回统计结果和明细
data:{
counter:{
image:4,
video:2
},
result:[
{...},
{...},
...
]
}
}
说明:编辑备忘内容
接口地址:'/data/editMemo'
请求方法:'put'
参数:
参数名 | 说明 | 值类型 | 是否必选 | 示例 |
---|---|---|---|---|
file_id | 文件 ID | String | 是 | - |
file_memo | 备忘内容 | String | 是 | - |
返回值:
{
code:808,
message:'操作成功'
}
说明:文件上传接口
接口地址:'/upload/upload'
请求方法:'post'
参数:
参数名 | 说明 | 值类型 | 是否必选 | 示例 |
---|---|---|---|---|
hash | 文件唯一性标识符 | String | 是 | - |
index | 文件切片索引 | String | 是 | - |
chunk | 文件切片 | Binary | 是 | - |
返回值:
{
//服务器自定义状态码
code:812,
//响应结果
message:'上传成功',
}
提示:
说明:切片全部上传后,请求此接口,可将切片重新合并成图像
接口地址:'/upload/completed'
请求方法:'post'
参数:
参数名 | 说明 | 值类型 | 是否必选 | 示例 |
---|---|---|---|---|
hash | 文件唯一性标识符 | String | 是 | |
chunkNum | 切片总数量 | Number | 是 | |
file_name | 文件名称 | String | 是 | i-1.jpg |
file_size | 文件大小 | Number | 是 | |
file_type | 文件类型 | String | 是 | image/jpeg、video/mp4 |
file_mini | 文件缩略图,base64 编码格式 | String | 是 | data:image/png;base64,iVB.... |
返回值:
{
code:808,
messge:'操作成功',
data:{
//文件ID
file_id:165689452888,
//文件名
file_name:'i-2.jpg',
//文件服务器地址
file_src:'http://127.0.0.1:3000/static/162656911656/image/origin/i-2.jpg',
//缩略图服务器地址
file_mini:'http://127.0.0.1:3000/static/162656911656/image/mini/e5feb634f48.png',
//文件所有者ID
file_owner:162656911656,
//文件上传年份
file_year:2021,
//文件上传月份
file_month:05,
//文件上传日期
file_day:12,
//文件上传完整时间
file_time:2021/05/12,
//文件大小
file_size:85625,
//文件类型
file_type:'image/jpg'
}
}
说明:将一张头像图片上传到服务器
接口地址:'/user/uploadAvatar'
请求方法:'post'
参数:
参数名 | 说明 | 值类型 | 是否必选 | 示例 |
---|---|---|---|---|
user_avatar | 用户头像图片 | File | 是 | - |
返回值:
{
code:812,
message:'上传成功'
}
提示:
说明:用户修改登录密码
接口地址:'/user/changePassword'
请求方法:'put'
参数:
参数名 | 说明 | 值类型 | 是否必选 | 示例 |
---|---|---|---|---|
user_password | 用户新密码 | String | 是 | - |
返回值:
{
code:808,
message:'操作成功'
}
说明:编辑用户密保问题和答案
接口地址:'/user/editQuestion'
请求方法:'post'
参数:
参数值 | 说明 | 值类型 | 是否必选 | 示例 |
---|---|---|---|---|
user_question | 用户密保问题 | String | 是 | - |
user_answer | 密保问题答案 | String | 是 | - |
返回值:
{
code: 808
message: "操作成功"
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。