前言
KV Cache是我去年11月写的一个KV存储的实践项目,功能很简单——把对数据库的各种操作转为Serverless API,你也可以认为这是一个可基于http请求进行操作的数据库。
项目地址:RavelloH/kv-cache: 基于 api 进行操作的缓存系统
随后,我又写了个网页用来快速操作数据库,类似于note.ms,可以把它当成是一个在线剪切板,非常适合在多个设备之前轻松传递文字内容。不过实现的方式比较邪道,这只是个404.html
,所以理论上部署在哪都行,这也算一种前后端分离吧(笑)
项目地址:RavelloH/kv-clipboard: 使用 kv-cache 项目为存储的在线剪切板前端
下面主要介绍的是KV Cache,前端那个结尾稍微提一下。
用途
因为有网就能访问Serverless API,就能操作数据库,所以你可以轻松的为你的任何能连网的项目增加一个非关系型数据库,同时也遵循KV数据库这样的键值对形式存储规则。不过在此项目中,为了确保各个数据独立安全,你需要使用uuid作为键名。
特点
安全
作为数据库首先需要保障内容的安全,虽然本项目是在KV数据库里明文存储你的内容的,不过在读取和写入的实现上做了很多安全保障。具体来说:
- 使用UUID作为键名,防止扫出存储的数据
- 可设定密码,需要密码才能查看\更改数据
- 可设定safeIP,只有某些IP地址的请求才能查看\更改数据(很适合固定公网IP的服务器使用)
- 可设定expiredTime,超过时间后删除数据
便捷
直接发送POST请求就能跟数据库交互了,方便。
快捷部署
作为一个Serverless项目可以轻松部署在各大云平台上。推荐使用Vercel,因为它会直接送你KV数据库。
使用
下面直接贴Github上面的文档了,毕竟这个项目也不会更新了,文档不会变动的
此API提供了数据的读写和删除功能。请求方法包括POST和GET。
写入数据
- 请求方法:POST
- 请求路径:
/api?mode=set
或/set
- 请求参数:
- data:要存储的数据(必选)
- password:访问数据时的密码(可选)
- safeIP:允许访问数据的IP地址范围(可选,示例:1.2-3.*.4)
- expiredTime:数据过期时间(可选,默认为7天)
- uuid:数据的唯一标识(可选,如果不提供则自动生成,输入已存在的uuid可覆盖原数据)
读取数据
请求数据有两种方法,可以以POST的方式请求,返回json格式的数据,或者以GET的方式请求,返回文本格式的数据
-
请求方法:POST
-
请求路径:
/api?mode=get
或/get
-
请求参数:
- uuid:要读取的数据的唯一标识(必选)
- password:访问数据时的密码(可选)
- shouldDelete:是否在读取数据后删除数据(可选,默认为false)
-
请求方法:GET
-
请求路径:
/api
或/
-
查询参数:
- uuid:要读取的数据的唯一标识(必选)
- password:访问数据时的密码(可选)
- shouldDelete:是否在读取数据后删除数据(可选,默认为false)
-
例子:
https://cache.ravelloh.top/?uuid=xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx&password=123456&shouldDelete=true
删除数据
- 请求方法:POST
- 请求路径:
/api?mode=del
或/del
- 请求参数:
- uuid:要删除的数据的唯一标识(必选)
检查服务状态
- 请求方法:GET
- 请求路径:
/api
- 响应参数:
- code:状态码(200表示正常)
- message:状态信息
- version:API版本号
- active:当前活动的数据数量
浏览器fetch请求示例
写入数据:
fetch('https://cache.ravelloh.top/api?mode=set', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
data: 'Hello, World!',
password: '123456',
safeIP: '*.*.*.*',
expiredTime: 24 * 60 * 60 * 1000,
uuid: 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'
})
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error(error));
读取数据:
fetch('https://cache.ravelloh.top/api?mode=get', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
uuid: 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx',
password: '123456',
shouldDelete: false
})
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error(error));
删除数据:
fetch('https://cache.ravelloh.top/api?mode=del', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
uuid: 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'
})
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error(error));
提醒信息
- 数据大小超过1MB的限制会返回错误。
- 密码长度超过128的限制会返回错误。
- IP规则不正确会返回错误,正确示例为:1.2-3.*.4。
- UUID格式错误会自动生成。
- 读取数据时,如果访问IP与存储数据的IP不匹配,会返回无权限错误。
- 读取数据时,如果提供的密码与存储数据的密码不匹配,会返回无效密码错误。
- 删除数据时,如果提供的UUID不存在,会返回删除失败错误。
部署
部署很轻松,实际上可以使用Vercel一键部署。
转到你的Vercel,在此页面中创建一个KV Database. vercel/stores尽量选择离你更近的服务地区,名称随意。如果切换了服务地区,你可稍后在下方的部署按钮部署结束后,在项目设置中更改你的项目serverless地区为服务器所在地区以提高性能。转到你的数据库页面,切换至.env.local
,如图。记录如下两项的值:
KV_REST_API_TOKEN
KV_REST_API_URL
image
之后,单击下方部署按钮,填入上方值即可一键部署。
前端剪切板
访问进去你会发现自己被重定向到了https://clip.ravelloh.top/xxxx,其实这里我随便写了个算法把任意字符串转为UUID,所以那个xxxx你可以随便输。算法我感觉挺满意的,放下面了。
async function stringToUUID(str) {
const encoder = new TextEncoder();
const data = encoder.encode(str);
// 使用SHA-1哈希函数进行哈希处理
const hashBuffer = await crypto.subtle.digest("SHA-1", data);
const hashArray = Array.from(new Uint8Array(hashBuffer));
// 将哈希值转换为16进制字符串
const hashHex = hashArray
.map((b) => b.toString(16).padStart(2, "0"))
.join("");
// 将哈希值转换为UUID格式
const uuid = [
hashHex.substring(0, 8),
hashHex.substring(8, 12),
hashHex.substring(12, 16),
hashHex.substring(16, 20),
// 截取20到32位,并设置版本和变体位
hashHex.substring(20, 24) +
"4" + // 设置版本为4
hashHex.substring(24, 36), // 变体位10xx
].join("-");
return uuid;
}
除此之外前端部分就没什么技术含量了,直接调用API就是。另外值得一提的是这个页面的实现方式,实际上你访问到的所有页面都是404.html,因为本来也没东西,所以会转到404,之后读取一下当前页面的地址直接转成UUID,跟KV Cache要数据就行。这些是我之前只会静态站的时候想到的歪门邪道的办法,我当时美其名曰“伪动态”,反正效果是达到了。