我的GitHub
0%

如何使用cf白嫖KV存储

背景

有时候写点小东西

总归是要有个地方持久化一些JSON数据

这些数据不多,专门弄个存储太重了

以前我都是看能不能放在纯前端的public,然后疯狂读写

现在我们有了更好的存储地方————CloudFlare

一.打开CloudFlare,创建KV空间

首页-存储和数据库-Workers KV

地址: https://dash.cloudflare.com/<:userId>/workers/kv/namespaces

新建一个命名空间,名字任意

二.创建一个workers服务

首页-计算和AI-Workers 和 Pages

名称任意,选个Hello World模板即可

点击保存

三.修改workers绑定和代码

添加绑定,选择KV空间

变量名称请写死为JSONBIN,空间选择上面创建的

然后点击编辑代码

代码地址: https://github.com/theowenyoung/blog/blob/main/scripts/jsonbin/main.js

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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
// Modify this
const APIKEY = "abc";

export default {
async fetch(request, env) {
try {
const responseBody = await handleRequest(request, env);
return new Response(responseBody, {
headers: {
"Content-Type": "application/json",
},
});
} catch (e) {
return errorToResponse(e);
}
},
};

async function handleRequest(request, env) {
if (!env.JSONBIN) {
throw new HTTPError(
"kvNotFound",
"Not Found KV Database Bind",
500,
"Internal Server Error"
);
}

// first check if the request is authorized
const { headers } = request;
const urlObj = new URL(request.url);
const authorization = headers.get("Authorization");
const headerAuthorizationValue = `Bearer ${APIKEY}`;
if (authorization) {
if (authorization !== headerAuthorizationValue) {
// if not authorized, return 401
throw new HTTPError(
"unauthorized",
"Authrorization Bearer abc is required",
401,
"Unauthorized"
);
}
} else if (urlObj.searchParams.has("key")) {
const keyFromQuery = urlObj.searchParams.get("key");
if (keyFromQuery !== APIKEY) {
throw new HTTPError(
"unauthorized",
"search query key=abc is required",
401,
"Unauthorized"
);
}
} else {
throw new HTTPError(
"unauthorized",
"Authrorization Bearer abc or search query key=abc is required",
401,
"Unauthorized"
);
}

// yes authorized, continue
if (request.method === "POST") {
const { pathname } = new URL(request.url);
let json = "";
try {
json = JSON.stringify(await request.json());
} catch (e) {
throw new HTTPError(
"jsonParseError",
"request body JSON is not valid, " + e.message,
400,
"Bad Request"
);
}
await env.JSONBIN.put(pathname, json);
return '{"ok":true}';
} else if (request.method === "GET") {
const { pathname } = new URL(request.url);
const value = await env.JSONBIN.get(pathname);
if (value === null) {
throw new HTTPError(
"notFound",
"Not Found",
404,
"The requested resource was not found"
);
}
return value;
} else {
throw new HTTPError(
"methodNotAllowed",
"Method Not Allowed",
405,
"The requested method is not allowed"
);
}
}

function errorToResponse(error) {
const bodyJson = {
ok: false,
error: "Internal Server Error",
message: "Internal Server Error",
};
let status = 500;
let statusText = "Internal Server Error";

if (error instanceof Error) {
bodyJson.message = error.message;
bodyJson.error = error.name;

if (error.status) {
status = error.status;
}
if (error.statusText) {
statusText = error.statusText;
}
}
return new Response(JSON.stringify(bodyJson, null, 2), {
status: status,
statusText: statusText,
headers: {
"Content-Type": "application/json",
},
});
}

class HTTPError extends Error {
constructor(name, message, status, statusText) {
super(message);
this.name = name;
this.status = status;
this.statusText = statusText;
}
}

注意修改第一行的Key

保存以后点击部署

四.测试

1
curl 'https://xx.xx.xx/foo/bar?key=abc' --data '{"foo":"bar"}'

1
curl 'https://xx.xx.xx/foo/bar?key=abc'

如果访问不行,记得挂代理

我是阿星,阿星的阿,阿星的星!