警告:コードリポジトリ(例:Github/GitLab)の濫用にはアカウント停止のリスクがあります!#
基本原理#
Pages は Git リポジトリを通じてデプロイされ、Workers は API キーを通じてあなたの Github リポジトリのディレクトリにアクセスし、クエリ API を公開します。Pages はこの API を読み取り、ファイルを表示します。
インスタンス#
Github リポジトリの作成#
- 教えません、簡単なヤピ。ネット上のチュートリアルは私の髪の毛よりも多いです。
- ルートディレクトリに
file
フォルダを作成し、以降のファイルのアップロードとダウンロードはこのフォルダ内で行います。 - ルートディレクトリに
index.html
を作成し、コードを記入します:
Body のクエリ API URL をあなたのものに変更します:
const response = await fetch('https://file-up.afo.im/list');
今は何に変更すればいいかわからないので、先に進んでください。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ファイルリスト</title>
<style>
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;
}
</style>
</head>
<body>
<h1>ファイルリスト</h1>
<ul id="file-list"></ul>
<script>
async function fetchFileList() {
try {
const response = await fetch('https://file-up.afo.im/list');
if (!response.ok) {
throw new Error('ファイルリストの取得に失敗しました');
}
const fileList = await response.text();
const files = fileList.split('\n').filter(file => file.trim() !== '');
displayFiles(files);
} catch (error) {
console.error('ファイルリストの取得エラー:', error);
document.getElementById('file-list').innerHTML = '<li>ファイルリストの取得エラー</li>';
}
}
function displayFiles(files) {
const fileListElement = document.getElementById('file-list');
fileListElement.innerHTML = files.map(file =>
`<li><a href="/file/${encodeURIComponent(file)}">${file}</a></li>`
).join('');
}
fetchFileList();
</script>
</body>
</html>
Workers の作成、API クエリとアップロードエンドポイントの公開#
- 教えません、簡単なヤピ。可視化Workers の作成、R2 に接続の R2 に接続する部分は見なくて大丈夫です。
- Workers のコードを変更します:
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('見つかりません', { status: 404 }))
}
}
function showLoginForm() {
const html = `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ログイン</title>
</head>
<body>
<h1>ログイン</h1>
<form action="/login" method="POST">
<input type="password" name="password" placeholder="パスワードを入力" required>
<button type="submit">ログイン</button>
</form>
<p><a href="/check-config">サーバー設定を確認</a></p>
</body>
</html>
`
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('無効なパスワード', { status: 401 })
}
}
function showUploadForm() {
const html = `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ファイルアップロード</title>
</head>
<body>
<h1>ファイルアップロード</h1>
<form action="/upload" method="POST" enctype="multipart/form-data">
<input type="file" name="file" required>
<button type="submit">アップロード</button>
</form>
</body>
</html>
`
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('アップロードされたファイルがありません', { 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: `アップロード ${file.name}`,
content: encodedContent
})
})
if (githubResponse.ok) {
return new Response('ファイルが正常にアップロードされました', { status: 200 })
} else {
const errorData = await githubResponse.text()
console.error('GitHub APIエラー:', errorData)
return new Response(`ファイルのアップロードに失敗しました: ${errorData}`, { status: 500 })
}
} catch (error) {
console.error('アップロードエラー:', error)
return new Response(`アップロード中のエラー: ${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エラー:', errorData)
return new Response(`ファイルリストの取得に失敗しました: ${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)
return new Response(`ファイル取得中のエラー: ${error.message}`, { status: 500 })
}
}
async function checkConfig() {
let configStatus = 'すべての設定は正しく行われています。'
if (!PASSWORD) {
configStatus = 'エラー: PASSWORDが設定されていません。'
} else if (!GITHUB_TOKEN) {
configStatus = 'エラー: GITHUB_TOKENが設定されていません。'
} else if (!GITHUB_REPO) {
configStatus = 'エラー: GITHUB_REPOが設定されていません。'
} 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 = `エラー: GitHub APIがエラーを返しました: ${data.message}`
} catch (jsonError) {
configStatus = `エラー: GitHub APIが非JSONレスポンスを返しました。ステータス: ${response.status}, 本文: ${responseText.substring(0, 100)}...`
}
} else {
try {
JSON.parse(responseText)
configStatus += ' GitHub接続成功。'
} catch (jsonError) {
configStatus = `警告: GitHub APIが非JSONレスポンスを返しましたが、接続は成功しました。ステータス: ${response.status}, 本文: ${responseText.substring(0, 100)}...`
}
}
} catch (error) {
configStatus = `エラー: GitHub APIへの接続に失敗しました: ${error.message}`
}
}
const html = `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>設定確認</title>
</head>
<body>
<h1>設定確認</h1>
<p>${configStatus}</p>
<a href="/">ログインに戻る</a>
</body>
</html>
`
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キー
。リポジトリ(Repository)の変更権限が必要です。
PASSWORD
はアップロードエンドポイントへのアクセスパスワードで、自分で設定します(Git でのアップロードを推奨します)。
-
あなたのカスタムドメインの
/list
にアクセスし、クエリ API が正常かどうか、リポジトリの file フォルダ内のファイルをリストできるか確認します。例えば:
- あなたの URL をGithub リポジトリの作成の 3 番目のステップに記入します。
const response = await fetch('https://file-up.afo.im/list');
https://file-up.afo.im/list
をあなたのものに置き換えます。
Pages の作成、Git リポジトリに接続#
-
教えません、簡単なヤピ。可視化あなたの最初のウェブサイトを構築する方法!サーバーなしで始められます!Git リポジトリを使用してデプロイすることに注意してください。ローカルデプロイではありません。
-
Cloudflare Pages はコミットがあると自動的に再デプロイされ、新しいファイルが自動的に更新されます。
アクセス#
- 書き急いでいるので、問題があればコメントで質問してください。