Files
hubproxy/ghproxy/public/wiki.html
2024-12-26 15:40:47 +08:00

592 lines
22 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=0">
<meta name="description" content="在线重定向Github链接支持API , Git 以及 Releases , Archive , gist , raw.githubusercontent.com 文件代理加速下载服务" />
<meta name="keywords" content="Sonder,git,github,proxy,github proxy,github代理,github加速,github下载,github下载加速,github文件加速,代理加速,加速下载" />
<meta name="language" content="zh-CN">
<title>GitHub文件加速</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css" integrity="sha512-1ycn6IcaQQ40/MKBW2W4Rhis/DbILU74C1vSrLJxCq57o941Ym01SwNsOMqvEBFlcgUa6xLiPY/NS5R+E6ztJQ==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<style>
@import url('https://font.sec.miui.com/font/css?family=MiSans:400,700:MiSans');
body {
font-family: 'MiSans', system-ui, -apple-system, sans-serif;
background: url('./bj.svg') no-repeat center center fixed;
background-size: cover;
color: #334155;
margin: 0;
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
* {
font-family: 'MiSans', system-ui, -apple-system, sans-serif;
}
.main-content {
background: white;
padding: 40px;
border-radius: 24px;
box-shadow: 0 4px 24px rgba(0, 0, 0, 0.04);
max-width: 800px;
width: calc(100% - 40px);
margin: 20px;
}
.title {
text-align: center;
font-size: 28px;
font-weight: 600;
margin-bottom: 32px;
color: #0f172a;
}
.mk-side-form {
display: flex;
gap: 12px;
margin-bottom: 24px;
padding: 16px;
border-radius: 16px;
}
#url-input {
flex: 1;
padding: 12px 16px;
border-radius: 12px;
border: 1px solid #e2e8f0;
font-size: 14px;
transition: all 0.2s ease;
background: white;
}
#url-input:focus {
border-color: #026d9f;
box-shadow: 0 0 0 3px rgba(14, 165, 233, 0.1);
}
#download-button, #copy-button, .mirror-check-button {
padding: 8px 16px;
border-radius: 8px;
font-size: 13px;
font-weight: 500;
transition: all 0.2s ease;
white-space: nowrap;
background: #555c5c;
color: white;
border: none;
outline: none;
cursor: pointer;
}
#download-button:hover, #copy-button:hover, .mirror-check-button:hover {
transform: translateY(-1px);
filter: brightness(1.2);
}
#copy-button {
background: #555c5c;
border: none;
outline: none;
}
.channel-container {
display: flex;
align-items: center;
gap: 16px;
padding: 16px;
border-radius: 16px;
margin-bottom: 24px;
}
.label {
color: #64748b;
font-size: 14px;
}
.channel-select {
flex: 1;
}
.channel-select select {
width: 100%;
padding: 12px 16px;
border-radius: 12px;
border: 1px solid #e2e8f0;
font-size: 14px;
background: white;
transition: all 0.2s ease;
cursor: pointer;
appearance: none;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2364748b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
background-repeat: no-repeat;
background-position: right 12px center;
background-size: 16px;
}
.channel-select select:focus {
border-color: #03618d;
box-shadow: 0 0 0 3px rgba(14, 165, 233, 0.1);
}
.mirror-check-button {
padding: 8px 16px;
border-radius: 8px;
font-size: 13px;
font-weight: 500;
transition: all 0.2s ease;
white-space: nowrap;
background: #555c5c;
color: white;
}
.mirror-check-button:hover {
transform: translateY(-1px);
filter: brightness(1.05);
}
.warning-box {
background: #fff7ed;
padding: 16px;
border-radius: 12px;
border-left: 3px solid #f97316;
margin-bottom: 24px;
font-size: 14px;
line-height: 1.5;
color: #9a3412;
}
.markdown-content {
padding: 24px;
border-radius: 16px;
}
.markdown-content h3 {
font-size: 18px;
margin-top: 0;
margin-bottom: 16px;
color: #0f172a;
}
.markdown-content ul, .markdown-content ol {
padding-left: 20px;
margin: 12px 0;
}
.markdown-content li {
margin-bottom: 8px;
font-size: 14px;
color: #334155;
}
.mirror-results {
display: grid;
gap: 8px;
margin-top: 20px;
}
.mirror-result {
background: white;
padding: 12px 16px;
border-radius: 12px;
display: grid;
grid-template-columns: minmax(200px, 2fr) 100px 80px auto;
align-items: center;
gap: 12px;
transition: all 0.2s ease;
border: 1px solid #e2e8f0;
}
.mirror-result:hover {
transform: translateY(-1px);
border-color: #02567d;
}
.mirror-result span {
font-size: 13px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.mirror-result .time,
.mirror-result .status-success,
.mirror-result .status-fail {
text-align: center;
}
.select-node-btn {
padding: 6px 12px;
background: #555c5c;
color: white;
border-radius: 6px;
font-size: 12px;
font-weight: 500;
transition: all 0.2s ease;
justify-self: end;
border: none;
outline: none;
cursor: pointer;
}
.select-node-btn:hover {
transform: translateY(-1px);
filter: brightness(1.2);
}
.progress-bar {
height: 4px;
background: #e2e8f0;
border-radius: 2px;
overflow: hidden;
margin: 16px 0 8px;
}
.progress-bar-fill {
height: 100%;
background: #0196db;
transition: width 0.3s ease;
}
#progressText {
font-size: 13px;
color: #64748b;
text-align: center;
}
.status-success {
color: #00a772;
}
.status-fail {
color: #dc2626;
}
.time {
color: #64748b;
font-size: 13px;
}
@media (max-width: 640px) {
.main-content {
padding: 24px;
margin: 16px;
width: calc(100% - 32px);
}
.mk-side-form {
flex-direction: column;
}
.channel-container {
flex-direction: column;
align-items: stretch;
}
.mirror-result {
grid-template-columns: 1fr;
gap: 8px;
}
.mirror-result span {
text-align: left;
}
.mirror-result .time,
.mirror-result .status-success,
.mirror-result .status-fail {
text-align: left;
}
.select-node-btn {
justify-self: start;
width: 100%;
}
}
.code-block {
background: #f7f8f9;
padding: 16px;
border-radius: 12px;
margin: 12px 0;
}
.code-block pre {
margin: 0;
font-family: 'MiSans', monospace;
}
.code-block code {
display: block;
white-space: pre-wrap;
word-wrap: break-word;
}
.back-button {
position: absolute;
top: 20px;
left: 20px;
padding: 8px 16px;
border-radius: 20px;
font-size: 13px;
font-weight: 500;
background: transparent;
color: #333;
border: 1px solid rgba(51, 51, 51, 0.5);
outline: none;
cursor: pointer;
transition: all 0.2s ease;
}
.back-button:hover {
transform: translateY(-1px);
background: rgba(0, 0, 0, 0.05);
}
</style>
</head>
<body>
<main class="main-content">
<button onclick="window.history.back()" class="back-button">返回</button>
<h1 class="title">GitHub 文件加速</h1>
<form id="url-form">
<div class="mk-side-form">
<input type="url" name="url" id="url-input" placeholder="请贴入 GitHub 的完整链接" required>
<button type="submit" id="download-button">下载</button>
<button type="button" id="copy-button">复制</button>
</div>
<div class="channel-container">
<div class="label">加速源:</div>
<div class="channel-select">
<select id="nodeSelector">
<!-- 选项将由 JavaScript 动态生成 -->
</select>
</div>
<button type="button" id="mirror-check-button" class="mirror-check-button">节点检测</button>
</div>
</form>
<div class="warning-box">
<strong>重要提示:</strong>
<font color="blue">公益服务,请勿滥用。</font>当前页面加速源来自网络收集整合。
</div>
<div id="mirror-results" class="mirror-results">
<!-- 节点测速结果将这里动态添加 -->
</div>
<div id="content-tips" class="markdown-content">
<h3>使用说明</h3>
<ol>
<li>支持GitHub文件、Releases、archive、gist、raw.githubusercontent.com文件下载</li>
<li>复制GitHub文件的原始链接粘贴到上方输入框。可直接点击加速下载或者复制完整的加速链接</li>
<li>输入的GitHub链接需要带https不支持项目文件夹的下载</li>
</ol>
<h3>页面合法输入示例</h3>
<ul>
<li>Raw 文件:<code>https://raw.githubusercontent.com/microsoft/vscode/main/LICENSE.txt</code></li>
<li>分支源码:<code>https://github.com/microsoft/vscode/archive/refs/heads/main.zip</code></li>
<li>Releases 文件:<code>https://github.com/github/gh-ost/releases/download/v1.1.6/gh-ost</code></li>
<li>Releases 源码:<code>https://github.com/microsoft/vscode/archive/refs/tags/1.82.3.zip</code></li>
</ul>
<h3>终端命令行示例</h3>
<h4>git clone</h4>
<div class="code-block">
<pre><code>git clone <font color="blue">https://ghproxy.cn</font>/https://github.com/microsoft/vscode.git</code></pre>
</div>
<h4>wget</h4>
<div class="code-block">
<pre><code>wget <font color="blue">https://ghproxy.cn</font>/https://github.com/microsoft/vscode/archive/refs/tags/1.82.3.zip</code></pre>
</div>
<h4>curl</h4>
<div class="code-block">
<pre><code>curl -O <font color="blue">https://ghproxy.cn</font>/https://github.com/microsoft/vscode/archive/refs/tags/1.82.3.zip</code></pre>
</div>
</div>
</main>
<script>
const nodes = [
{ value: "https://ghproxy.cn", text: "ghproxy.cn" },
{ value: "https://gh.llkk.cc", text: "gh.llkk.cc" },
{ value: "https://github.moeyy.xyz", text: "github.moeyy.xyz" },
{ value: "https://ghproxy.net", text: "ghproxy.net" },
{ value: "https://gitproxy.click", text: "gitproxy.click" },
{ value: "https://gh-proxy.com", text: "gh-proxy.com" },
{ value: "https://gh.chaoyi996.com", text: "gh.chaoyi996.com" },
{ value: "https://gh.sixyin.com", text: "gh.sixyin.com" },
{ value: "https://ghproxy.imciel.com", text: "ghproxy.imciel.com" },
{ value: "https://gh.idayer.com", text: "gh.idayer.com" },
{ value: "https://gh-proxy.llyke.com", text: "gh-proxy.llyke.com" },
{ value: "https://githubapi.jjchizha.com", text: "githubapi.jjchizha.com" },
{ value: "https://gh.monlor.com", text: "gh.monlor.com" },
{ value: "https://g.blfrp.cn", text: "g.blfrp.cn" },
{ value: "https://hub.gitmirror.com", text: "hub.gitmirror.com" },
{ value: "https://ghp.keleyaa.com", text: "ghp.keleyaa.com" },
{ value: "https://ghp.p3terx.com", text: "ghp.p3terx.com" },
{ value: "https://gh.tryxd.cn", text: "gh.tryxd.cn" },
{ value: "https://ghp.miaostay.com", text: "ghp.miaostay.com" },
{ value: "https://gh.xx9527.cn", text: "gh.xx9527.cn" },
{ value: "https://gh.qninq.cn", text: "gh.qninq.cn" },
{ value: "https://gitproxy.mrhjx.cn", text: "gitproxy.mrhjx.cn" },
{ value: "https://github.limoruirui.com", text: "github.limoruirui.com" },
{ value: "https://gh.6yit.com", text: "gh.6yit.com" },
{ value: "https://mirror.ghproxy.com", text: "mirror.ghproxy.com" },
{ value: "https://mirrors.chenby.cn", text: "mirrors.chenby.cn" },
{ value: "https://ghproxy.xiaopa.cc", text: "ghproxy.xiaopa.cc" },
{ value: "https://ghpr.cc", text: "ghpr.cc" },
{ value: "https://gh.api.99988866.xyz", text: "gh.api.99988866.xyz" },
{ value: "https://gh.zwy.me", text: "gh.zwy.me" },
{ value: "https://cf.ghproxy.cc", text: "cf.ghproxy.cc" },
{ value: "https://git.886.be", text: "git.886.be" },
{ value: "https://gh.xxooo.cf", text: "gh.xxooo.cf" },
{ value: "https://gh.tt.ma", text: "gh.tt.ma" },
{ value: "https://git.speed-ssr.tech", text: "git.speed-ssr.tech" },
{ value: "https://gh.noki.icu", text: "gh.noki.icu" },
{ value: "https://gh-proxy.ygxz.in", text: "gh-proxy.ygxz.in" },
{ value: "https://gh.catmak.name", text: "gh.catmak.name" },
{ value: "https://github.xxlab.tech", text: "github.xxlab.tech" },
{ value: "https://ql.133.info", text: "ql.133.info" },
{ value: "https://liqiu.love", text: "liqiu.love" },
{ value: "https://gh.pylas.xyz", text: "gh.pylas.xyz" },
{ value: "https://ghp.arslantu.xyz", text: "ghp.arslantu.xyz" },
{ value: "https://cdn.moran233.xyz", text: "cdn.moran233.xyz" },
{ value: "https://gh.zhaojun.im", text: "gh.zhaojun.im" },
{ value: "https://gp.zkitefly.eu.org", text: "gp.zkitefly.eu.org" },
{ value: "https://firewall.lxstd.org", text: "firewall.lxstd.org" },
{ value: "https://github.ednovas.xyz", text: "github.ednovas.xyz" },
{ value: "https://proxy.yaoyaoling.net", text: "proxy.yaoyaoling.net" },
{ value: "https://git.669966.xyz", text: "git.669966.xyz" },
{ value: "https://ghproxy.1888866.xyz", text: "ghproxy.1888866.xyz" },
{ value: "https://git.40609891.xyz", text: "git.40609891.xyz" },
{ value: "https://gh.jasonzeng.dev", text: "gh.jasonzeng.dev" },
{ value: "https://gh.222322.xyz", text: "gh.222322.xyz" },
{ value: "https://ghproxy.cianogame.top", text: "ghproxy.cianogame.top" },
{ value: "https://gh.ddlc.top", text: "gh.ddlc.top" },
{ value: "https://gh.nxnow.top", text: "gh.nxnow.top" },
{ value: "https://github.7boe.top", text: "github.7boe.top" },
{ value: "https://ghproxy.cnproxy.top", text: "ghproxy.cnproxy.top" },
];
const mirrorCheckButton = document.getElementById('mirror-check-button');
const progressContainer = document.createElement('div');
progressContainer.id = 'progressContainer';
progressContainer.style.display = 'none';
progressContainer.innerHTML = `
<div class="progress-bar">
<div class="progress-bar-fill"></div>
</div>
<div id="progressText">0%</div>
`;
document.querySelector('.main-content').insertBefore(progressContainer, document.getElementById('mirror-results'));
const progressBarFill = progressContainer.querySelector('.progress-bar-fill');
const progressText = progressContainer.querySelector('#progressText');
const mirrorResults = document.getElementById('mirror-results');
const nodeSelector = document.getElementById('nodeSelector');
const urlInput = document.getElementById('url-input');
const copyButton = document.getElementById('copy-button');
// 初始化下拉选择器
const initializeNodeSelector = () => {
nodeSelector.innerHTML = '';
nodes.forEach(mirror => {
const option = document.createElement('option');
option.value = mirror.value;
option.textContent = mirror.text;
nodeSelector.appendChild(option);
});
};
// 测试单个节点的延迟
const testMirror = async (mirror) => {
const start = Date.now();
try {
const response = await fetch(`${mirror}/https://raw.githubusercontent.com/microsoft/vscode/main/LICENSE.txt?t=${Date.now()}`);
if (response.ok) {
const time = Date.now() - start;
return { mirror, time, success: true };
} else {
return { mirror, time: null, success: false };
}
} catch (error) {
return { mirror, time: null, success: false };
}
};
// 更新进度条
const updateProgress = (completed, total) => {
const percentage = Math.round((completed / total) * 100);
progressBarFill.style.width = `${percentage}%`;
progressText.textContent = `${percentage}%`;
};
// 运行节点测速
const runMirrorCheck = async () => {
progressContainer.style.display = 'block';
mirrorResults.innerHTML = '';
let completed = 0;
const total = nodes.length;
for (const mirror of nodes) {
const result = await testMirror(mirror.value);
const resultDiv = document.createElement('div');
resultDiv.className = 'mirror-result';
resultDiv.innerHTML = `
<span>${result.mirror}</span>
<span class="time">${result.time ? `${result.time}ms` : 'N/A'}</span>
<span class="${result.success ? 'status-success' : 'status-fail'}">${result.success ? '成功' : '失败'}</span>
${result.success ? `<button class="select-node-btn" data-mirror="${result.mirror}">选择此节点</button>` : ''}
`;
mirrorResults.appendChild(resultDiv);
completed++;
updateProgress(completed, total);
}
};
// 提交表单时的事件处理函数
document.addEventListener('DOMContentLoaded', function () {
initializeNodeSelector();
document.getElementById('url-form').addEventListener('submit', function (e) {
e.preventDefault();
const url = urlInput.value;
if (url.toLowerCase().indexOf("github".toLowerCase()) < 0) {
alert("当前页面仅用于加速下载来自 GitHub 的资源!");
} else {
let channelSelect = nodeSelector.value;
if (!channelSelect.endsWith('/')) channelSelect += '/';
const fullUrl = channelSelect + url;
window.open(fullUrl);
}
});
});
// 绑定节点测速按钮事件
mirrorCheckButton.addEventListener('click', runMirrorCheck);
// 绑定选择节点按钮事件
mirrorResults.addEventListener('click', function (e) {
if (e.target.classList.contains('select-node-btn')) {
const selectedMirror = e.target.getAttribute('data-mirror');
nodeSelector.value = selectedMirror;
}
});
// 绑定复制按钮事件
copyButton.addEventListener('click', function () {
const url = urlInput.value;
if (url.toLowerCase().indexOf("github".toLowerCase()) < 0) {
alert("请输入有效的 GitHub 完整链接!");
} else {
let channelSelect = nodeSelector.value;
if (!channelSelect.endsWith('/')) channelSelect += '/';
const fullUrl = channelSelect + url;
navigator.clipboard.writeText(fullUrl).then(() => {
alert("完整链接已复制到剪贴板!");
});
}
});
</script>
</body>
</html>