优化random接口的读取策略

This commit is contained in:
MarSeventh
2024-12-20 19:18:55 +08:00
parent 83bba5944f
commit 2748200c59
5 changed files with 50 additions and 93 deletions

View File

@@ -53,6 +53,7 @@ Add Features:
- 管理端批量操作支持按照用户选择的顺序进行([#issue124](https://github.com/MarSeventh/CloudFlare-ImgBed/issues/124)
- `random`接口优化减少KV操作次数增加`content`参数,支持返回指定类型的文件
- 接入CloudFlare Cache API提升 list 相关接口访问速度
- 正常读取返回图片的CDN缓存时间从1年调整为7天防止缓存清除不成功的情况下图片长时间内仍可以访问的问题
## 2024.12.14

View File

@@ -1,67 +0,0 @@
export async function onRequest(context) {
// Contents of context object
const {
request, // same as existing Worker API
env, // same as existing Worker API
params, // if filename includes [id] or [[path]]
waitUntil, // same as ctx.waitUntil in existing Worker API
next, // used for middleware or to fetch assets
data, // arbitrary space for passing data between middlewares
} = context;
// 检查是否启用了随机图功能
if (env.AllowRandom != "true") {
return new Response(JSON.stringify({ error: "Random is disabled" }), { status: 403 });
}
// 检查是否配置了KV数据库
if (typeof env.img_url == "undefined" || env.img_url == null || env.img_url == "") {
return new Response('Error: Please configure KV database', { status: 500 });
}
// 看缓存中是否有记录,有则直接返回
const cache = caches.default;
const cacheRes = await cache.match(request.url);
if (cacheRes) {
return cacheRes;
}
// 缓存未命中
let allRecords = [];
let cursor = null;
do {
const records = await env.img_url.list({
limit: 1000,
cursor,
});
// 除去records中key以manage@开头的记录
records.keys = records.keys.filter(item => !item.name.startsWith("manage@"));
// 保留metadata中fileType为image或video的记录
records.keys = records.keys.filter(item => item.metadata?.FileType?.includes("image") || item.metadata?.FileType?.includes("video"));
allRecords.push(...records.keys);
cursor = records.cursor;
} while (cursor);
// 仅保留记录的name和metadata中的FileType字段
allRecords = allRecords.map(item => {
return {
name: item.name,
FileType: item.metadata?.FileType
}
});
// 返回所有记录
const info = JSON.stringify(allRecords);
const res = new Response(info,{
headers: {
"Content-Type": "application/json",
}
});
// 缓存结果缓存时间为24小时
await cache.put(request.url, res.clone(), {
expirationTtl: 24 * 60 * 60
});
return res;
}

View File

@@ -76,11 +76,11 @@ export async function onRequest(context) { // Contents of context object
if (fileType) {
headers.set('Content-Type', fileType);
}
// 根据Referer设置CDN缓存策略如果是从/或/dashboard等访问则仅允许浏览器缓存否则设置为public缓存时间为1年
// 根据Referer设置CDN缓存策略如果是从/或/dashboard等访问则仅允许浏览器缓存否则设置为public缓存时间为7天
if (Referer && Referer.includes(url.origin)) {
headers.set('Cache-Control', 'private, max-age=86400');
} else {
headers.set('Cache-Control', 'public, max-age=31536000');
headers.set('Cache-Control', 'public, max-age=604800');
}
// 返回图片
@@ -136,11 +136,11 @@ export async function onRequest(context) { // Contents of context object
if (fileType) {
headers.set('Content-Type', fileType);
}
// 根据Referer设置CDN缓存策略如果是从/或/dashboard等访问则仅允许浏览器缓存否则设置为public缓存时间为1年
// 根据Referer设置CDN缓存策略如果是从/或/dashboard等访问则仅允许浏览器缓存否则设置为public缓存时间为7天
if (Referer && Referer.includes(url.origin)) {
headers.set('Cache-Control', 'private, max-age=86400');
} else {
headers.set('Cache-Control', 'public, max-age=31536000');
headers.set('Cache-Control', 'public, max-age=604800');
}
const newRes = new Response(response.body, {

View File

@@ -1,20 +0,0 @@
export async function onRequestPost(context) {
// Contents of context object
const {
request, // same as existing Worker API
env, // same as existing Worker API
params, // if filename includes [id] or [[path]]
waitUntil, // same as ctx.waitUntil in existing Worker API
next, // used for middleware or to fetch assets
data, // arbitrary space for passing data between middlewares
} = context;
//从POST请求中获取authCode
const jsonRequest = await request.json();
const authCode = jsonRequest.authCode;
//验证authCode
if (env.AUTH_CODE !== undefined && authCode !== env.AUTH_CODE) {
return new Response('Unauthorized', { status: 401 })
}
//返回登录成功
return new Response('Login success', { status: 200 })
}

View File

@@ -29,8 +29,7 @@ export async function onRequest(context) {
}
// 调用randomFileList接口读取KV数据库中的所有记录
let allRecords = [];
allRecords = JSON.parse(await fetch(requestUrl.origin + '/api/randomFileList').then(res => res.text()));
let allRecords = await getRandomFileList(env, requestUrl);
// 筛选出符合fileType要求的记录
allRecords = allRecords.filter(item => { return fileType.some(type => item.FileType.includes(type)) });
@@ -73,3 +72,47 @@ export async function onRequest(context) {
}
}
}
async function getRandomFileList(env, url) {
// 检查缓存中是否有记录,有则直接返回
const cache = caches.default;
const cacheRes = await cache.match(`${url.origin}/api/randomFileList`);
if (cacheRes) {
return JSON.parse(await cacheRes.text());
}
let allRecords = [];
let cursor = null;
do {
const records = await env.img_url.list({
limit: 1000,
cursor,
});
// 除去records中key以manage@开头的记录
records.keys = records.keys.filter(item => !item.name.startsWith("manage@"));
// 保留metadata中fileType为image或video的记录
records.keys = records.keys.filter(item => item.metadata?.FileType?.includes("image") || item.metadata?.FileType?.includes("video"));
allRecords.push(...records.keys);
cursor = records.cursor;
} while (cursor);
// 仅保留记录的name和metadata中的FileType字段
allRecords = allRecords.map(item => {
return {
name: item.name,
FileType: item.metadata?.FileType
}
});
// 缓存结果缓存时间为24小时
await cache.put(`${url.origin}/api/randomFileList`, new Response(JSON.stringify(allRecords), {
headers: {
"Content-Type": "application/json",
}
}), {
expirationTtl: 24 * 60 * 60
});
return allRecords;
}