教程仅供参考,但绝对小白,免费,反正我本人确实成功了,而且没花钱。
小白零成本搭建永久个人图床教程(基础+进阶一键拖传)
很多人找图床都踩过坑:公共图床删图、失效、限速、有广告,付费图床又觉得不划算。我也是从纯小白一步步摸索,踩了无数坑,终于搭出一套完全免费、稳定不炸链、自主可控、全球加速的个人图床,现在把全过程整理成保姆级教程,零基础也能跟着做,自己掌控所有图片,再也不用担心链接失效!
整套方案用到:GitHub(存储备份)+ Cloudflare Pages(CDN加速+镜像)+ 自定义域名,全程免费,无任何隐藏收费,个人使用完全够用!
一、前期准备(零成本,5分钟搞定)
1. 必备账号
- 注册 GitHub 账号:github.com
- 注册 Cloudflare 账号:cloudflare.com
- 自定义域名(可选,没有也能用)
2. 核心原理(小白易懂)
- GitHub:只做图片备份仓库,不直接对外访问
- Cloudflare Pages:镜像 GitHub 仓库,做图片加速访问
- 手动部署:关闭自动构建,节省每月 500 次构建额度
二、第一步:创建 GitHub 存储仓库
- 登录 GitHub,点击右上角 + 号 → New repository
- 仓库名自定义,选择 Public
- 勾选 Add a README file,创建仓库
- 在仓库里新建 img 文件夹,统一存放图片
三、第二步:Cloudflare Pages 绑定 GitHub 仓库
- 进入 Cloudflare → Pages → 创建项目 → 连接到 Git
- 授权并选择你的图床仓库
- 构建设置:构建命令留空,输出目录 /
- 保存并部署,等待完成
四、第三步:最关键!关闭自动部署(必做)
- 进入 Pages 项目 → 设置 → 构建与部署
- 找到分支控制,取消勾选「启用自动生产分支部署」
- 预览分支选择「无」
- 保存后,传图不再疯狂消耗构建次数
关闭自动部署后,图片上传后不会立刻生效,需要你手动点一次「重新部署」。
五、第四步:绑定自定义域名(可选)
- Pages → 自定义域 → 添加自定义域
- 输入 img.xxx.com 这类子域名
- 按提示完成 DNS 解析
六、第五步:日常上传+使用流程
- 去 GitHub 上传图片到 img 文件夹
- 回到 Cloudflare Pages 点「重新部署」
- 链接格式:https://你的域名/img/文件名.png
七、扩容方案:突破 20000 文件上限
一个 Pages 项目最多 20000 个文件,满了就:
- 新建一个 GitHub 仓库
- 新建一个 Pages 项目绑定它
- 绑定新子域名如 img1.xxx.com
- 想建多少个就建多少个
八、必看避坑指南
- 不要开自动部署,否则传一张扣一次构建
- 单文件不要超过 25MB
- 图片存在 GitHub,Pages 只是加速
- 不传违规内容,账号永远安全
- 攒一批图再部署,更省次数
进阶教程:浏览器一键拖传(不用登 GitHub)
基础版需要登 GitHub 传图,进阶版实现:拖拽上传、自动生成链接、纯本地 HTML 运行,不用服务器、不用后台、复制即用。
一、生成 GitHub 上传令牌
- GitHub → 头像 → Settings → Developer settings
- Personal access tokens → Generate new token (classic)
- 名称随便写,过期选永久,只勾 repo 权限
- 生成后立刻复制,只显示一次
二、一键拖传 HTML 代码
新建记事本,粘贴下面代码,改好配置,保存为 upload.html 即可使用。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>个人图床一键上传</title>
<style>
*{margin:0;padding:0;box-sizing:border-box;font-family:Arial,sans-serif;}
body{max-width:800px;margin:50px auto;padding:0 20px;background:#f5f5f5;}
.upload-box{border:2px dashed #409eff;border-radius:10px;padding:60px 20px;text-align:center;background:#fff;cursor:pointer;margin-bottom:30px;}
.upload-box:hover{background:#f0f8ff;}
.upload-box input{display:none;}
.upload-btn{background:#409eff;color:#fff;border:none;padding:12px 30px;border-radius:5px;cursor:pointer;font-size:16px;margin-bottom:20px;}
.upload-btn:disabled{background:#ccc;cursor:not-allowed;}
.link-item{background:#fff;padding:15px;border-radius:5px;margin-bottom:10px;word-break:break-all;}
.copy-btn{background:#67c23a;color:#fff;border:none;padding:5px 10px;border-radius:3px;cursor:pointer;margin-left:10px;}
</style>
</head>
<body>
<h2>个人图床一键拖拽上传</h2>
<br>
<div class="upload-box" id="dropBox">
<p>拖拽图片到此处 / 点击选择图片</p>
<input type="file" id="fileInput" multiple accept="image/*">
</div>
<button class="upload-btn" id="uploadBtn" disabled>开始上传</button>
<div id="linkList"></div>
<script>
// ========== 请修改以下3个配置信息 ==========
const GITHUB_TOKEN = "你的GitHub令牌";
const GITHUB_USERNAME = "你的GitHub用户名";
const GITHUB_REPO = "你的图床仓库名";
// ========== 配置结束 ==========
const DOMAIN = "https://img.xxx.com";
let selectedFiles = [];
const fileInput = document.getElementById("fileInput");
const dropBox = document.getElementById("dropBox");
const uploadBtn = document.getElementById("uploadBtn");
const linkList = document.getElementById("linkList");
dropBox.addEventListener("click", ()=>fileInput.click());
dropBox.addEventListener("dragover",(e)=>{e.preventDefault();dropBox.style.background="#e8f4ff";});
dropBox.addEventListener("dragleave",()=>{dropBox.style.background="#fff";});
dropBox.addEventListener("drop",(e)=>{
e.preventDefault();dropBox.style.background="#fff";
selectedFiles=Array.from(e.dataTransfer.files);
uploadBtn.disabled=selectedFiles.length===0;
});
fileInput.addEventListener("change",()=>{
selectedFiles=Array.from(fileInput.files);
uploadBtn.disabled=selectedFiles.length===0;
});
uploadBtn.addEventListener("click",async ()=>{
uploadBtn.disabled=true;uploadBtn.textContent="上传中...";linkList.innerHTML="";
for(const file of selectedFiles){
const reader=new FileReader();reader.readAsDataURL(file);
reader.onload=async ()=>{
const base64=reader.result.split(",")[1];
const timestamp=new Date().getTime();
const fileName=`${timestamp}_${file.name}`;
const apiUrl=`https://api.github.com/repos/${GITHUB_USERNAME}/${GITHUB_REPO}/contents/img/${fileName}`;
try{
const res=await fetch(apiUrl,{
method:"PUT",
headers:{
"Authorization":`token ${GITHUB_TOKEN}`,
"Content-Type":"application/json"
},
body:JSON.stringify({message:`上传:${fileName}`,content:base64})
});
if(res.ok){
const u=`${DOMAIN}/img/${fileName}`;
linkList.innerHTML+=`<div class="link-item"><span>${u}</span><button class="copy-btn" onclick="copyLink('${u}')">复制</button></div>`;
}
}catch(e){
linkList.innerHTML+=`<div class="link-item" style="color:red">${file.name} 上传失败</div>`;
}
};
}
uploadBtn.textContent="开始上传";uploadBtn.disabled=false;
});
function copyLink(u){navigator.clipboard.writeText(u).then(()=>alert("复制成功"));}
</script>
</body>
</html>
三、进阶使用说明
- 直接双击 upload.html 打开使用
- 支持拖拽、多选图片
- 上传后去 Pages 手动部署一次才生效
- 令牌只存在本地,不会泄露
整套最终流程
- 打开 upload.html 拖拽传图
- Cloudflare Pages 重新部署
- 复制链接直接使用