778 字
4 分钟
基于github托管图片
TIP请不要过度滥用这个项目,仅提供思路。
之前就在想解决图床的问题,使用第三方图床的话会有失效的风险,毕竟不是存储在自己的服务器上,那么有没有什么解决办法呢?
兄弟有的有的,经过我的探索,我发现完全可以将图片直接放到github仓库上,白嫖GitHub。
本站使用的是基于Astro的博客,项目本身就是托管在gh上的,所以我在项目的根目录下创建了一个image文件夹,用来存放图片。
这样push后就将图片一并传到gh上了,在自己的仓库中可以找到图片的直链地址,
例如我的某张图片的url就是https://raw.githubusercontent.com/Flygeon/Astro/refs/heads/main/image/6-cover.png。
反代图片
但是这个方法有个很大的问题,由于天朝网络的因素,国内访问就和窜西一样时好时坏,所以我们还需要构建一个反代项目来解决这个问题。这点可以通过大善人Cloudflare来实现。
新建一个Cloudflare Pages项目就够了,不需要挤占Workers资源。
新建一个_worker.js文件,往里面填充如下代码:
// _worker.js - 完整的 raw.githubusercontent.com 反向代理// 部署到 Cloudflare Pages 即可使用
// 配置区域(可根据需要修改)const TARGET_HOST = "raw.githubusercontent.com"; // 目标主机const ENABLE_CORS = true; // 是否启用跨域资源共享const ENABLE_CACHE = true; // 是否启用缓存(默认缓存 1 天)const CACHE_TTL = 86400; // 缓存时间(秒),默认 1 天const ALLOWED_REFERERS = []; // 防盗链白名单,留空则不检查,例如 ["https://yourdomain.com"]
export default { async fetch(request, env, ctx) { try { // 1. 防盗链检查(可选) if (ALLOWED_REFERERS.length > 0) { const referer = request.headers.get("Referer"); if (referer) { let isAllowed = false; for (const allowed of ALLOWED_REFERERS) { if (referer.startsWith(allowed)) { isAllowed = true; break; } } if (!isAllowed) { return new Response("Forbidden", { status: 403 }); } } }
// 2. 构建目标 URL let url = new URL(request.url); url.protocol = "https"; url.hostname = TARGET_HOST; // 保持原始路径、查询参数不变
// 3. 创建新的请求,复制原始请求的方法、头、正文 let newRequest = new Request(url, { method: request.method, headers: request.headers, body: request.body, // 保留请求的 duplex 属性(用于流式传输) duplex: "half" });
// 4. 发送请求到 GitHub raw 服务器 let response = await fetch(newRequest);
// 5. 准备响应头(复制原始响应头并修改) let responseHeaders = new Headers(response.headers);
// 6. 启用 CORS(跨域资源共享) if (ENABLE_CORS) { responseHeaders.set("Access-Control-Allow-Origin", "*"); responseHeaders.set("Access-Control-Allow-Methods", "GET, HEAD, OPTIONS"); responseHeaders.set("Access-Control-Allow-Headers", "Content-Type"); // 处理预检请求(OPTIONS) if (request.method === "OPTIONS") { return new Response(null, { status: 204, headers: responseHeaders }); } }
// 7. 启用缓存(通过 Cache-Control 头) if (ENABLE_CACHE && response.status === 200) { // 如果原始响应没有 Cache-Control,则添加 if (!responseHeaders.has("Cache-Control")) { responseHeaders.set("Cache-Control", `public, max-age=${CACHE_TTL}`); } }
// 8. 可选:隐藏代理标识(假装自己是原始服务器) responseHeaders.set("Via", ""); // 移除 Via 头 responseHeaders.delete("CF-Cache-Status"); // 移除 Cloudflare 特有头
// 9. 返回最终响应 return new Response(response.body, { status: response.status, statusText: response.statusText, headers: responseHeaders });
} catch (error) { // 错误处理:返回 500 错误信息 return new Response(`Proxy Error: ${error.message}`, { status: 500 }); } }};然后自定义你的域名,测试一下访问,All done.