Cloudflare连接Github！代码仓库当网盘！

WARNING：滥用代码仓库（如 Github/GitLab）可能有封号风险！

基本原理

Pages 通过 Git 存储库部署，Workers 通过 API Key 访问你的 Github 仓库目录开放查询 API，Pages 读取这个 API，展示文件

实例

创建 Github 仓库

不教了，简单的雅痞。网上的教程比我的头发还多

根目录创建file文件夹，后续的文件上传下载都在这个文件夹

根目录创建index.html，填写代码：
更改 Body 的查询 API URL 为你的：
const response = await fetch('https://file-up.afo.im/list');
你目前不知道要改成什么，先往下看

Copy





File List

body {
font-family: Arial, sans-serif;
padding: 20px;
}
ul {
list-style-type: none;
padding: 0;
}
li {
margin: 5px 0;
}
a {
text-decoration: none;
color: #007bff;
}
a:hover {
text-decoration: underline;
}



File List



async function fetchFileList() {
try {
const response = await fetch('https://file-up.afo.im/list');
if (!response.ok) {
throw new Error('Failed to fetch file list');
}
const fileList = await response.text();
const files = fileList.split('\n').filter(file => file.trim() !== '');
displayFiles(files);
} catch (error) {
console.error('Error fetching file list:', error);
document.getElementById('file-list').innerHTML = ' Error fetching file list ';
}
}

function displayFiles(files) {
const fileListElement = document.getElementById('file-list');
fileListElement.innerHTML = files.map(file =>
` ${file} `
).join('');
}

fetchFileList();




创建 Workers，开放 API 查询和上传端点

不教了，简单的雅痞。可见创建 Workers，连接 R2不用看连接 R2 的部分

更改 Workers 代码：

Copy
addEventListener('fetch', event => {
event.respondWith(handleRequest(event.request))
})

async function handleRequest(request) {
const url = new URL(request.url)
const path = url.pathname

if (path === '/') {
return addCORSHeaders(showLoginForm())
} else if (path === '/login') {
return addCORSHeaders(await handleLogin(request))
} else if (path === '/upload') {
return addCORSHeaders(await handleUpload(request))
} else if (path === '/check-config') {
return addCORSHeaders(await checkConfig())
} else if (path === '/list') {
return addCORSHeaders(await listFiles()) // 允许直接访问 /list，无需授权
} else {
return addCORSHeaders(new Response('Not Found', { status: 404 }))
}
}

function showLoginForm() {
const html = `





Login


Login


Login

Check server configuration


`
return new Response(html, {
headers: { 'Content-Type': 'text/html' }
})
}

async function handleLogin(request) {
const formData = await request.formData()
const password = formData.get('password')

if (password === PASSWORD) {
return showUploadForm()
} else {
return new Response('Invalid password', { status: 401 })
}
}

function showUploadForm() {
const html = `





File Upload


File Upload


Upload



`
return new Response(html, {
headers: { 'Content-Type': 'text/html' }
})
}

async function handleUpload(request) {
try {
const formData = await request.formData()
const file = formData.get('file')

if (!file) {
return new Response('No file uploaded', { status: 400 })
}

const content = await file.arrayBuffer()
const encodedContent = btoa(String.fromCharCode.apply(null, new Uint8Array(content)))

const githubResponse = await fetch(`https://api.github.com/repos/${GITHUB_REPO}/contents/file/${file.name}`, {
method: 'PUT',
headers: {
'Authorization': `token ${GITHUB_TOKEN}`,
'Content-Type': 'application/json',
'User-Agent': 'Cloudflare Worker'
},
body: JSON.stringify({
message: `Upload ${file.name}`,
content: encodedContent
})
})

if (githubResponse.ok) {
return new Response('File uploaded successfully', { status: 200 })
} else {
const errorData = await githubResponse.text()
console.error('GitHub API Error:', errorData)
return new Response(`Failed to upload file: ${errorData}`, { status: 500 })
}
} catch (error) {
console.error('Upload error:', error)
return new Response(`Error during upload: ${error.message}`, { status: 500 })
}
}

async function listFiles() {
try {
const githubResponse = await fetch(`https://api.github.com/repos/${GITHUB_REPO}/contents/file`, {
headers: {
'Authorization': `token ${GITHUB_TOKEN}`,
'User-Agent': 'Cloudflare Worker'
}
})

if (!githubResponse.ok) {
const errorData = await githubResponse.text()
console.error('GitHub API Error:', errorData)
return new Response(`Failed to fetch file list: ${errorData}`, { status: 500 })
}

const files = await githubResponse.json()

// 将文件名转换为纯文本，一行一个
const fileNames = files.map(file => file.name).join('\n')

return new Response(fileNames, {
headers: { 'Content-Type': 'text/plain' }
})
} catch (error) {
console.error('Error fetching files:', error)
return new Response(`Error during fetching files: ${error.message}`, { status: 500 })
}
}

async function checkConfig() {
let configStatus = 'All configurations are set correctly.'

if (!PASSWORD) {
configStatus = 'ERROR: PASSWORD is not set.'
} else if (!GITHUB_TOKEN) {
configStatus = 'ERROR: GITHUB_TOKEN is not set.'
} else if (!GITHUB_REPO) {
configStatus = 'ERROR: GITHUB_REPO is not set.'
} else {
try {
const response = await fetch(`https://api.github.com/repos/${GITHUB_REPO}`, {
headers: {
'Authorization': `token ${GITHUB_TOKEN}`,
'User-Agent': 'Cloudflare Worker'
}
})

const responseText = await response.text()

if (!response.ok) {
try {
const data = JSON.parse(responseText)
configStatus = `ERROR: GitHub API returned an error: ${data.message}`
} catch (jsonError) {
configStatus = `ERROR: GitHub API returned a non-JSON response. Status: ${response.status}, Body: ${responseText.substring(0, 100)}...`
}
} else {
try {
JSON.parse(responseText)
configStatus += ' GitHub connection successful.'
} catch (jsonError) {
configStatus = `WARNING: GitHub API returned a non-JSON response, but the connection was successful. Status: ${response.status}, Body: ${responseText.substring(0, 100)}...`
}
}
} catch (error) {
configStatus = `ERROR: Failed to connect to GitHub API: ${error.message}`
}
}

const html = `





Configuration Check


Configuration Check
${configStatus}
Back to Login


`

return new Response(html, {
status: 200,
headers: { 'Content-Type': 'text/html' }
})
}

// 添加 CORS 头
function addCORSHeaders(response) {
const headers = new Headers(response.headers)
headers.set('Access-Control-Allow-Origin', '*')
headers.set('Access-Control-Allow-Methods', 'GET, POST, PUT, OPTIONS')
headers.set('Access-Control-Allow-Headers', 'Content-Type')

return new Response(response.body, {
status: response.status,
statusText: response.statusText,
headers
})
}

为 Workers 添加变量
GITHUB_REPO格式为：Github用户名/Github仓库名
GITHUB_TOKEN格式为：你的Github API Key。需要有仓库（Repository）修改权限
PASSWORD为访问上传端点的密码，自行设置（更建议使用 Git 上传）

访问你的自定义域的/list，看看查询 API 是否正常，是否能列出仓库下 file 文件夹下的文件，如

将你的 URL 填入创建 Github 仓库的第三步中的

const response = await fetch('https://file-up.afo.im/list');
替换https://file-up.afo.im/list为你的

创建 Pages，连接 Git 存储库

不教了，简单的雅痞。可见教你搭建你的第一个网站！无需服务器即可上手！注意要用 Git 存储库部署而不是本地部署

Cloudflare Pages 当有提交时会自动重新部署，实现新文件自动更新

访问

写的仓促，有问题评论问