const domain = 'example.com';
const adminPath = 'admin'; // 自定义管理路径
const USERNAME = USERNAME_ENV;
const PASSWORD = PASSWORD_ENV;
const sessionStore = new Map();
const SESSION_EXPIRY_TIME = 5 * 60 * 1000;
// 监听 fetch 事件
addEventListener('fetch', event => {
event.respondWith(handleRequest(event.request));
});
// 处理请求
async function handleRequest(request) {
const { pathname } = new URL(request.url);
switch (pathname) {
case '/':
return handleRootRequest(); // 处理根请求
case `/${adminPath}`:
return handleAdminRequest(request); // 处理管理请求
case '/upload':
return request.method === 'POST' ? handleUploadRequest(request) : new Response('Method Not Allowed', { status: 405 }); // 处理上传请求
case '/bing-images':
return handleBingImagesRequest(); // 处理 Bing 图片请求
case '/delete-images':
return handleDeleteImagesRequest(request); // 处理删除请求
default:
return handleImageRequest(pathname); // 处理图片请求
}
}
// 处理根请求,返回首页 HTML
function handleRootRequest() {
return new Response(`
Telegraph图床
项目开源于 GitHub - 0-RTT/telegraph
`, { headers: { 'Content-Type': 'text/html;charset=UTF-8' } });
}
// 处理管理请求,进行身份验证
async function handleAdminRequest(request) {
const authHeader = request.headers.get('Authorization');
const sessionId = request.headers.get('Session-Id');
if (sessionId && sessionStore.has(sessionId)) {
const sessionData = sessionStore.get(sessionId);
if (Date.now() < sessionData.expiry) {
return await generateAdminPage(); // 返回管理页面
} else {
sessionStore.delete(sessionId); // 删除过期会话
}
}
if (!authHeader || !isValidAuth(authHeader)) {
return new Response('需要身份验证', {
status: 401,
headers: {
'WWW-Authenticate': 'Basic realm="Admin Area"',
'Content-Type': 'text/plain; charset=utf-8' // 添加字符集
}
});
}
const newSessionId = generateSessionId(); // 生成新会话 ID
sessionStore.set(newSessionId, { expiry: Date.now() + SESSION_EXPIRY_TIME });
const response = await generateAdminPage(); // 生成管理页面
response.headers.set('Session-Id', newSessionId); // 设置会话 ID
return response;
}
// 生成随机会话 ID
function generateSessionId() {
return Math.random().toString(36).substr(2, 9);
}
// 生成管理页面的 HTML
async function generateAdminPage() {
const { keys } = await imgurl.list();
// 并发获取所有媒体信息
const responses = await Promise.all(keys.map(key => imgurl.get(key.name)));
// 将键和对应的值组合成数组
const mediaData = responses.map((value, index) => {
if (value) {
const key = keys[index].name;
const { timestamp, url } = JSON.parse(value); // 解析存储的 JSON 对象
return { key, timestamp, url };
}
return null;
}).filter(item => item !== null); // 过滤掉无效项
// 按照时间戳排序(从新到旧)
mediaData.sort((a, b) => b.timestamp - a.timestamp);
const mediaHtml = mediaData.map(({ key, url, timestamp }) => {
const fileExtension = url.split('.').pop().toLowerCase(); // 获取文件后缀
if (fileExtension === 'mp4') {
return `
`;
} else {
return `
上传时间: ${new Date(timestamp).toLocaleString('zh-CN', { timeZone: 'Asia/Shanghai' })}
`;
}
}).join('');
const html = `
图库
${mediaHtml}
`;
return new Response(html, { status: 200, headers: { 'Content-Type': 'text/html; charset=utf-8' } });
}
// 验证身份
function isValidAuth(authHeader) {
const [scheme, encoded] = authHeader.split(' ');
if (scheme !== 'Basic') return false;
const decoded = atob(encoded);
const [username, password] = decoded.split(':');
return username === USERNAME && password === PASSWORD;
}
// 处理文件上传请求
async function handleUploadRequest(request) {
try {
const formData = await request.formData();
const file = formData.get('file');
if (!file) throw new Error('缺少文件');
const response = await fetch('https://telegra.ph/upload', {
method: 'POST',
body: formData
});
if (!response.ok) throw new Error('上传失败');
const responseData = await response.json();
const imageKey = responseData[0].src;
const imageURL = `https://${domain}${imageKey}`;
// 获取当前时间戳
const timestamp = Date.now();
// 将时间戳和 URL 存储到 KV 中
await imgurl.put(imageKey, JSON.stringify({ timestamp, url: imageURL }));
return new Response(JSON.stringify({ data: imageURL }), {
status: 200,
headers: { 'Content-Type': 'application/json' }
});
} catch (error) {
console.error('内部服务器错误:', error);
return new Response(JSON.stringify({ error: '内部服务器错误' }), { status: 500, headers: { 'Content-Type': 'application/json' } });
}
}
// 处理 Bing 图片请求
async function handleBingImagesRequest() {
const res = await fetch(`https://cn.bing.com/HPImageArchive.aspx?format=js&idx=0&n=5`);
const bing_data = await res.json();
const images = bing_data.images.map(image => ({
url: `https://cn.bing.com${image.url}`
}));
const return_data = {
status: true,
message: "操作成功",
data: images
};
return new Response(JSON.stringify(return_data), {
status: 200,
headers: { 'Content-Type': 'application/json' }
});
}
// 处理图片请求
async function handleImageRequest(pathname) {
const foundValue = await imgurl.get(pathname);
if (foundValue) {
const url = new URL(JSON.parse(foundValue).url); // 解析存储的 JSON 对象以获取 URL
url.hostname = 'telegra.ph'; // 确保请求的主机名是 telegra.ph
return fetch(url); // 返回图片内容
}
// 直接返回 404 响应
return new Response(null, { status: 404 }); // 返回空响应和 404 状态码
}
// 处理删除请求
async function handleDeleteImagesRequest(request) {
if (request.method !== 'POST') {
return new Response('Method Not Allowed', { status: 405 });
}
try {
const keysToDelete = await request.json();
for (const key of keysToDelete) {
await imgurl.delete(key); // 从 KV 中删除图片
}
return new Response(JSON.stringify({ message: '删除成功' }), { status: 200 });
} catch (error) {
console.error('删除图片时出错:', error);
return new Response(JSON.stringify({ error: '删除失败' }), { status: 500 });
}
}