今天是第二十五天我們可以寫一個 javascript 連結github程式碼網頁程式管理系統,以下是我的程式碼
首先,你需要在 GitHub Developer Settings 中建立一個 OAuth 應用程式。獲得以下資訊:
Client ID
Client Secret
http://localhost:3000/callback
用戶點擊登入按鈕時,會被重定向到 GitHub 登入頁面,授權完成後重定向回你的應用。
// 用戶點擊時重定向到 GitHub OAuth 登入頁面
function redirectToGitHubOAuth() {
const clientId = '你的-client-id'; // 使用你在 GitHub 取得的 Client ID
const redirectUri = 'http://localhost:3000/callback'; // 你設定的重定向 URI
const scope = 'repo'; // 設置權限範圍,如存取所有儲存庫
const authUrl = `https://github.com/login/oauth/authorize?client_id=${clientId}&redirect_uri=${redirectUri}&scope=${scope}`;
window.location.href = authUrl;
}
當 GitHub 重定向回你的應用後,你需要將 code
發送到你的伺服器(或直接在前端處理,取決於應用設計),以獲得存取令牌。
// OAuth 回調處理邏輯
function handleOAuthCallback() {
const urlParams = new URLSearchParams(window.location.search);
const code = urlParams.get('code');
if (code) {
// 將 'code' 發送到伺服器換取存取令牌
fetch('https://your-server.com/oauth/callback', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ code }),
})
.then(response => response.json())
.then(data => {
// 存儲存取令牌,後續請求中需要
const accessToken = data.access_token;
localStorage.setItem('github_token', accessToken);
loadRepositories();
});
}
}
透過 GitHub API 和存取令牌來取得使用者的儲存庫列表。
// 使用存取令牌從 GitHub API 獲取使用者儲存庫列表
function loadRepositories() {
const token = localStorage.getItem('github_token');
fetch('https://api.github.com/user/repos', {
headers: {
Authorization: `Bearer ${token}`
}
})
.then(response => response.json())
.then(repos => {
const repoList = document.getElementById('repo-list');
repoList.innerHTML = ''; // 清空列表
repos.forEach(repo => {
const listItem = document.createElement('li');
listItem.innerHTML = `<a href="#" onclick="loadCommits('${repo.full_name}')">${repo.name}</a>`;
repoList.appendChild(listItem);
});
});
}
點選儲存庫名稱後,載入並顯示提交紀錄。
// 根據選定儲存庫的名稱載入其提交紀錄
function loadCommits(repoFullName) {
const token = localStorage.getItem('github_token');
fetch(`https://api.github.com/repos/${repoFullName}/commits`, {
headers: {
Authorization: `Bearer ${token}`
}
})
.then(response => response.json())
.then(commits => {
const commitList = document.getElementById('commit-list');
commitList.innerHTML = ''; // 清空提交紀錄列表
commits.forEach(commit => {
const listItem = document.createElement('li');
listItem.innerHTML = `${commit.commit.author.name}: ${commit.commit.message}`;
commitList.appendChild(listItem);
});
});
}
你可以讓使用者查看、建立或更新儲存庫中的 issue。
// 取得儲存庫的所有 issue
function loadIssues(repoFullName) {
const token = localStorage.getItem('github_token');
fetch(`https://api.github.com/repos/${repoFullName}/issues`, {
headers: {
Authorization: `Bearer ${token}`
}
})
.then(response => response.json())
.then(issues => {
const issueList = document.getElementById('issue-list');
issueList.innerHTML = ''; // 清空 issue 列表
issues.forEach(issue => {
const listItem = document.createElement('li');
listItem.innerHTML = `${issue.title}: ${issue.body}`;
issueList.appendChild(listItem);
});
});
}
// 建立新 issue
function createIssue(repoFullName, issueTitle, issueBody) {
const token = localStorage.getItem('github_token');
fetch(`https://api.github.com/repos/${repoFullName}/issues`, {
method: 'POST',
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
title: issueTitle,
body: issueBody
})
})
.then(response => response.json())
.then(issue => {
alert(`Issue created: ${issue.title}`);
loadIssues(repoFullName); // 更新 issue 列表
});
}
你可以使用 Bootstrap 或其他前端框架來建立一個簡單易用的 UI:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>GitHub Repo Manager</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet">
<script defer src="app.js"></script>
</head>
<body>
<div class="container">
<h1>GitHub 程式碼管理系統</h1>
<button class="btn btn-primary" onclick="redirectToGitHubOAuth()">登入 GitHub</button>
<h2>你的儲存庫</h2>
<ul id="repo-list"></ul>
<h3>提交紀錄</h3>
<ul id="commit-list"></ul>
<h3>Issue 列表</h3>
<ul id="issue-list"></ul>
</div>
</body>
</html>
redirectToGitHubOAuth
函數)這段程式碼的目的是引導使用者到 GitHub OAuth 登錄頁面,請求授權來存取其 GitHub 帳戶的資料。
function redirectToGitHubOAuth() {
const clientId = '你的-client-id'; // 使用你在 GitHub 取得的 Client ID
const redirectUri = 'http://localhost:3000/callback'; // 你設定的重定向 URI
const scope = 'repo'; // 設置權限範圍,如存取所有儲存庫
const authUrl = `https://github.com/login/oauth/authorize?client_id=${clientId}&redirect_uri=${redirectUri}&scope=${scope}`;
window.location.href = authUrl;
}
clientId
:這是你在 GitHub 開發者設定中註冊的 OAuth 應用程式時,GitHub 提供的客戶端 ID。這個 ID 會識別你的應用程式。redirectUri
:這是使用者授權後,GitHub 將其重定向的 URL,應該是你應用程式的某個 URL。當使用者授權後,GitHub 會將授權碼(code
)發送到這個 URI。scope
:表示你希望存取的 GitHub 資料範圍,例如 repo
代表儲存庫相關的資料。window.location.href
:這行程式碼會將使用者導向到 GitHub OAuth 認證頁面。當使用者同意授權後,GitHub 會將使用者重定向回你的應用程式,並附帶授權碼。
handleOAuthCallback
函數)當使用者從 GitHub 重定向回你的應用程式時,這個函數會處理回調中的授權碼,並用該授權碼換取存取令牌。
function handleOAuthCallback() {
const urlParams = new URLSearchParams(window.location.search);
const code = urlParams.get('code');
if (code) {
fetch('https://your-server.com/oauth/callback', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ code }),
})
.then(response => response.json())
.then(data => {
const accessToken = data.access_token;
localStorage.setItem('github_token', accessToken);
loadRepositories();
});
}
}
urlParams
:這段程式碼用來從 URL 中擷取查詢參數,並取得 GitHub 發送回來的授權碼(code
)。fetch
:將授權碼發送到後端伺服器,後端伺服器會用該授權碼請求存取令牌(access_token
)。localStorage.setItem
:將從 GitHub 獲取的 access_token
存儲在瀏覽器的 localStorage
中,供後續的 API 請求使用。loadRepositories
:當成功獲得存取令牌後,自動載入使用者的儲存庫列表。loadRepositories
函數)這個函數使用 GitHub API 來取得使用者的儲存庫列表,並顯示在網頁上。
function loadRepositories() {
const token = localStorage.getItem('github_token');
fetch('https://api.github.com/user/repos', {
headers: {
Authorization: `Bearer ${token}`
}
})
.then(response => response.json())
.then(repos => {
const repoList = document.getElementById('repo-list');
repoList.innerHTML = ''; // 清空列表
repos.forEach(repo => {
const listItem = document.createElement('li');
listItem.innerHTML = `<a href="#" onclick="loadCommits('${repo.full_name}')">${repo.name}</a>`;
repoList.appendChild(listItem);
});
});
}
localStorage.getItem('github_token')
:從 localStorage
中獲取存取令牌。fetch
:向 GitHub API 發送 GET 請求來獲取使用者的儲存庫列表。API URL 是 https://api.github.com/user/repos
,而存取令牌被作為 Authorization 標頭的一部分發送(Bearer
認證模式)。repos
:API 回應的是一個儲存庫的列表。repoList.innerHTML = '';
:清空現有的列表。forEach
:遍歷回應的儲存庫列表,並將每個儲存庫添加到頁面上作為連結。點擊連結時會加載該儲存庫的提交紀錄。loadCommits
函數)當使用者點擊某個儲存庫名稱時,這個函數會使用 GitHub API 來載入該儲存庫的提交紀錄。
function loadCommits(repoFullName) {
const token = localStorage.getItem('github_token');
fetch(`https://api.github.com/repos/${repoFullName}/commits`, {
headers: {
Authorization: `Bearer ${token}`
}
})
.then(response => response.json())
.then(commits => {
const commitList = document.getElementById('commit-list');
commitList.innerHTML = ''; // 清空提交紀錄列表
commits.forEach(commit => {
const listItem = document.createElement('li');
listItem.innerHTML = `${commit.commit.author.name}: ${commit.commit.message}`;
commitList.appendChild(listItem);
});
});
}
repoFullName
:儲存庫的完整名稱(包括擁有者和儲存庫名稱),例如 username/repository
。fetch
:這裡我們使用 GitHub API 來取得特定儲存庫的提交紀錄。API URL 是 https://api.github.com/repos/${repoFullName}/commits
。commits
:API 回應的是該儲存庫的提交紀錄列表。forEach
:遍歷提交紀錄,將每個提交的作者名稱和提交訊息顯示在頁面上。loadIssues
和 createIssue
函數)這兩個函數分別用於載入儲存庫的 issue 和建立新的 issue。
function loadIssues(repoFullName) {
const token = localStorage.getItem('github_token');
fetch(`https://api.github.com/repos/${repoFullName}/issues`, {
headers: {
Authorization: `Bearer ${token}`
}
})
.then(response => response.json())
.then(issues => {
const issueList = document.getElementById('issue-list');
issueList.innerHTML = ''; // 清空 issue 列表
issues.forEach(issue => {
const listItem = document.createElement('li');
listItem.innerHTML = `${issue.title}: ${issue.body}`;
issueList.appendChild(listItem);
});
});
}
function createIssue(repoFullName, issueTitle, issueBody) {
const token = localStorage.getItem('github_token');
fetch(`https://api.github.com/repos/${repoFullName}/issues`, {
method: 'POST',
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
title: issueTitle,
body: issueBody
})
})
.then(response => response.json())
.then(issue => {
alert(`Issue created: ${issue.title}`);
loadIssues(repoFullName); // 更新 issue 列表
});
}
loadIssues
:這個函數用來從 GitHub API 中獲取儲存庫的所有 issue,並顯示在頁面上。createIssue
:這個函數用來建立新 issue。使用 POST 方法向 GitHub API 發送請求,並在主體中傳送 issue 的標題和內容。最後
,這段程式碼包含了簡單的前端 HTML,用來顯示儲存庫、提交紀錄和 issue。
<ul id="repo-list"></ul>
<ul id="commit-list"></ul>
<ul id="issue-list"></ul>
repo-list
:用來顯示使用者的 GitHub 儲存庫列表。commit-list
:用來顯示儲存庫的提交紀錄。issue-list
:用來顯示儲存庫的 issue。這個程式碼展示了如何使用 GitHub OAuth 來實現授權,並透過 GitHub API 獲取使用者的儲存庫、提交紀錄和 issue。