mirror of
https://github.com/woodchen-ink/docker-image.git
synced 2025-07-18 14:01:59 +08:00
feat(handler, reference): Refactor home page to external HTML and update styles
This commit is contained in:
parent
dc03f2246f
commit
a069c13542
173
src/handler.ts
173
src/handler.ts
@ -1,168 +1,3 @@
|
|||||||
function getHomePageHtml(): string {
|
|
||||||
return `
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>CZL Docker镜像服务</title>
|
|
||||||
<link rel="shortcut icon" href="https://cdn-oracle.czl.net/img/2024/08/66c8417602ba0.ico">
|
|
||||||
<style>
|
|
||||||
body {
|
|
||||||
font-family: system-ui, -apple-system,BlinkMacSystemFont,'Helvetica Neue',Helvetica,Segoe UI,Arial,Roboto,'PingFang SC',miui,'Hiragino Sans GB','Microsoft Yahei',sans-serif ;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
height: 100vh;
|
|
||||||
background-image: url('https://random-api.czl.net/pic/all');
|
|
||||||
background-size: cover;
|
|
||||||
background-position: center;
|
|
||||||
color: white;
|
|
||||||
text-shadow: 1px 1px 2px black;
|
|
||||||
}
|
|
||||||
.container {
|
|
||||||
background-color: rgba(0, 0, 0, 0.5);
|
|
||||||
padding: 20px;
|
|
||||||
border-radius: 10px;
|
|
||||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
|
|
||||||
max-width: 600px;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
.step {
|
|
||||||
margin-bottom: 1em;
|
|
||||||
}
|
|
||||||
.step label {
|
|
||||||
margin-bottom: 0.5em;
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
.step .input-group {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
.step textarea,
|
|
||||||
.step input {
|
|
||||||
flex: 1;
|
|
||||||
padding: 10px;
|
|
||||||
border-radius: 5px;
|
|
||||||
border: none;
|
|
||||||
margin-right: 10px;
|
|
||||||
color: black;
|
|
||||||
}
|
|
||||||
.button, .icon-button {
|
|
||||||
background-color: #4CAF50;
|
|
||||||
color: white;
|
|
||||||
padding: 10px 20px;
|
|
||||||
margin: 0 10px;
|
|
||||||
border: none;
|
|
||||||
border-radius: 5px;
|
|
||||||
cursor: pointer;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
min-width: 40px;
|
|
||||||
min-height: 40px;
|
|
||||||
}
|
|
||||||
.button:hover, .icon-button:hover {
|
|
||||||
background-color: #45a049;
|
|
||||||
}
|
|
||||||
.icon-button i {
|
|
||||||
font-size: 18px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div class="container">
|
|
||||||
<h1>快捷命令</h1>
|
|
||||||
<div class="step" style="color:blue;">
|
|
||||||
提示,支持docker.io, ghcr,quay,k8sgcr,gcr, 非docker.io需加上域名前缀
|
|
||||||
</div>
|
|
||||||
<div class="step">
|
|
||||||
<label>第一步:输入原始镜像地址获取命令.</label>
|
|
||||||
<div class="input-group">
|
|
||||||
<input type="text" id="imageInput" placeholder="woodchen/simplemirrorfetch" />
|
|
||||||
<button class="button" id="generateButton">获取命令</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="step">
|
|
||||||
<label>第二步:代理拉取镜像</label>
|
|
||||||
<div class="input-group">
|
|
||||||
<textarea id="dockerPullCommand" readonly></textarea>
|
|
||||||
<button class="icon-button" onclick="copyToClipboard('dockerPullCommand')"><i>📋</i></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="step">
|
|
||||||
<label>第三步:重命名镜像</label>
|
|
||||||
<div class="input-group">
|
|
||||||
<textarea id="dockerTagCommand" readonly></textarea>
|
|
||||||
<button class="icon-button" onclick="copyToClipboard('dockerTagCommand')"><i>📋</i></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="step">
|
|
||||||
<label>第四步:删除代理镜像</label>
|
|
||||||
<div class="input-group">
|
|
||||||
<textarea id="dockerRmiCommand" readonly></textarea>
|
|
||||||
<button class="icon-button" onclick="copyToClipboard('dockerRmiCommand')"><i>📋</i></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<script>
|
|
||||||
document.addEventListener('DOMContentLoaded', (event) => {
|
|
||||||
document.getElementById('generateButton').addEventListener('click', generateCommands);
|
|
||||||
});
|
|
||||||
|
|
||||||
function generateCommands() {
|
|
||||||
const imageInput = document.getElementById('imageInput').value;
|
|
||||||
const source = getSourceFromImage(imageInput);
|
|
||||||
const imageName = getImageNameFromInput(imageInput, source);
|
|
||||||
const dockerPullCommand = \`docker pull \${source}/\${imageName}\`;
|
|
||||||
const dockerTagCommand = \`docker tag \${source}/\${imageName} \${imageName}\`;
|
|
||||||
const dockerRmiCommand = \`docker rmi \${source}/\${imageName}\`;
|
|
||||||
|
|
||||||
document.getElementById('dockerPullCommand').value = dockerPullCommand;
|
|
||||||
document.getElementById('dockerTagCommand').value = dockerTagCommand;
|
|
||||||
document.getElementById('dockerRmiCommand').value = dockerRmiCommand;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getSourceFromImage(imageInput) {
|
|
||||||
const currentDomain = window.location.hostname;
|
|
||||||
if (imageInput.startsWith("gcr.io/")) {
|
|
||||||
return \`\${currentDomain}/gcr\`;
|
|
||||||
} else if (imageInput.startsWith("k8s.gcr.io/")) {
|
|
||||||
return \`\${currentDomain}/k8sgcr\`;
|
|
||||||
} else if (imageInput.startsWith("quay.io/")) {
|
|
||||||
return \`\${currentDomain}/quay\`;
|
|
||||||
} else if (imageInput.startsWith("ghcr.io/")) {
|
|
||||||
return \`\${currentDomain}/ghcr\`;
|
|
||||||
} else {
|
|
||||||
return currentDomain;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getImageNameFromInput(imageInput, source) {
|
|
||||||
if (imageInput.startsWith("gcr.io/")) {
|
|
||||||
return imageInput.replace("gcr.io/", "");
|
|
||||||
} else if (imageInput.startsWith("k8s.gcr.io/")) {
|
|
||||||
return imageInput.replace("k8s.gcr.io/", "");
|
|
||||||
} else if (imageInput.startsWith("quay.io/")) {
|
|
||||||
return imageInput.replace("quay.io/", "");
|
|
||||||
} else if (imageInput.startsWith("ghcr.io/")) {
|
|
||||||
return imageInput.replace("ghcr.io/", "");
|
|
||||||
} else {
|
|
||||||
return imageInput;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function copyToClipboard(elementId) {
|
|
||||||
const copyText = document.getElementById(elementId);
|
|
||||||
copyText.select();
|
|
||||||
copyText.setSelectionRange(0, 99999); // For mobile devices
|
|
||||||
document.execCommand('copy');
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
import { TokenProvider } from './token'
|
import { TokenProvider } from './token'
|
||||||
import { Backend } from './backend'
|
import { Backend } from './backend'
|
||||||
|
|
||||||
@ -183,14 +18,18 @@ export async function handleRequest(request: Request): Promise<Response> {
|
|||||||
const url = new URL(request.url)
|
const url = new URL(request.url)
|
||||||
|
|
||||||
if (url.pathname === '/') {
|
if (url.pathname === '/') {
|
||||||
return new Response(getHomePageHtml(), {
|
return new Response(null, {
|
||||||
headers: { 'content-type': 'text/html;charset=UTF-8' },
|
status: 301,
|
||||||
|
headers: {
|
||||||
|
'Location': 'https://onepage.czl.net/tools/docker_mirror.html'
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return handleRegistryRequest(request)
|
return handleRegistryRequest(request)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function copyProxyHeaders(inputHeaders: Headers): Headers {
|
function copyProxyHeaders(inputHeaders: Headers): Headers {
|
||||||
const headers = new Headers;
|
const headers = new Headers;
|
||||||
for (const pair of inputHeaders.entries()) {
|
for (const pair of inputHeaders.entries()) {
|
||||||
|
183
参考.html
Normal file
183
参考.html
Normal file
@ -0,0 +1,183 @@
|
|||||||
|
<html lang="zh-CN">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<title>CZL Docker镜像服务</title>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<meta name="description"
|
||||||
|
content="CZL Docker镜像服务提供了一个简单的界面来生成代理拉取、重命名和删除Docker镜像的命令。支持多种镜像源,包括docker.io, ghcr, quay, k8sgcr, gcr等。">
|
||||||
|
<link rel="shortcut icon" href="https://i-aws.czl.net/r2/2023/06/20/649168ec9d6a8.ico">
|
||||||
|
<link rel="stylesheet" href="https://i-aws.czl.net/cdnjs/ajax/libs/mdui/2.1.3/mdui.min.css" />
|
||||||
|
<script src="https://i-aws.czl.net/cdnjs/ajax/libs/mdui/2.1.3/mdui.global.js"></script>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
height: 100vh;
|
||||||
|
background-image: url('https://random-api.czl.net/pic/all');
|
||||||
|
background-size: cover;
|
||||||
|
background-position: center;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
background-color: rgba(0, 0, 0, 0.5);
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 10px;
|
||||||
|
box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
|
||||||
|
max-width: 600px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.step {
|
||||||
|
margin-bottom: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.step label {
|
||||||
|
margin-bottom: 0.5em;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.step .input-group {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.step textarea,
|
||||||
|
.step input {
|
||||||
|
flex: 1;
|
||||||
|
padding: 10px;
|
||||||
|
border-radius: 5px;
|
||||||
|
border: none;
|
||||||
|
margin-right: 10px;
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button,
|
||||||
|
.icon-button {
|
||||||
|
background-color: #4CAF50;
|
||||||
|
color: white;
|
||||||
|
padding: 10px 20px;
|
||||||
|
margin: 0 10px;
|
||||||
|
border: none;
|
||||||
|
border-radius: 5px;
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
min-width: 40px;
|
||||||
|
min-height: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button:hover,
|
||||||
|
.icon-button:hover {
|
||||||
|
background-color: #45a049;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-button i {
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div id="nav-container"></div>
|
||||||
|
<script src="./nav.js"></script>
|
||||||
|
<script>document.addEventListener('DOMContentLoaded', initNavigation);</script>
|
||||||
|
<div class="container">
|
||||||
|
<h1>快捷命令</h1>
|
||||||
|
<div class="step" style="color:rgb(255, 0, 170); text-shadow: 1px 1px 2px black;">
|
||||||
|
提示,支持docker.io, ghcr,quay,k8sgcr,gcr, 非docker.io需加上域名前缀<br>
|
||||||
|
例如:woodchen/simplemirrorfetch <br> gcr.io/woodchen/simplemirrorfetch <br> quay.io/woodchen/simplemirrorfetch<br>
|
||||||
|
ghcr.io/woodchen/simplemirrorfetch<br> k8s.gcr.io/woodchen/simplemirrorfetch
|
||||||
|
</div>
|
||||||
|
<div class="step">
|
||||||
|
<label>第一步:输入原始镜像地址获取命令.</label>
|
||||||
|
<div class="input-group">
|
||||||
|
<input type="text" id="imageInput" placeholder="woodchen/simplemirrorfetch" />
|
||||||
|
<button class="button" id="generateButton">获取命令</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="step">
|
||||||
|
<label>第二步:代理拉取镜像</label>
|
||||||
|
<div class="input-group">
|
||||||
|
<textarea id="dockerPullCommand" readonly></textarea>
|
||||||
|
<button class="icon-button" onclick="copyToClipboard('dockerPullCommand')"><i>📋</i></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="step">
|
||||||
|
<label>第三步:重命名镜像</label>
|
||||||
|
<div class="input-group">
|
||||||
|
<textarea id="dockerTagCommand" readonly></textarea>
|
||||||
|
<button class="icon-button" onclick="copyToClipboard('dockerTagCommand')"><i>📋</i></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="step">
|
||||||
|
<label>第四步:删除代理镜像</label>
|
||||||
|
<div class="input-group">
|
||||||
|
<textarea id="dockerRmiCommand" readonly></textarea>
|
||||||
|
<button class="icon-button" onclick="copyToClipboard('dockerRmiCommand')"><i>📋</i></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
document.addEventListener('DOMContentLoaded', (event) => {
|
||||||
|
document.getElementById('generateButton').addEventListener('click', generateCommands);
|
||||||
|
});
|
||||||
|
|
||||||
|
function generateCommands() {
|
||||||
|
const imageInput = document.getElementById('imageInput').value;
|
||||||
|
const source = getSourceFromImage(imageInput);
|
||||||
|
const imageName = getImageNameFromInput(imageInput, source);
|
||||||
|
const dockerPullCommand = `docker pull ${source}/${imageName}`;
|
||||||
|
const dockerTagCommand = `docker tag ${source}/${imageName} ${imageName}`;
|
||||||
|
const dockerRmiCommand = `docker rmi ${source}/${imageName}`;
|
||||||
|
|
||||||
|
document.getElementById('dockerPullCommand').value = dockerPullCommand;
|
||||||
|
document.getElementById('dockerTagCommand').value = dockerTagCommand;
|
||||||
|
document.getElementById('dockerRmiCommand').value = dockerRmiCommand;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSourceFromImage(imageInput) {
|
||||||
|
const currentDomain = 'docker-mirror.czl.net';
|
||||||
|
if (imageInput.startsWith("gcr.io/")) {
|
||||||
|
return `${currentDomain}/gcr`;
|
||||||
|
} else if (imageInput.startsWith("k8s.gcr.io/")) {
|
||||||
|
return `${currentDomain}/k8sgcr`;
|
||||||
|
} else if (imageInput.startsWith("quay.io/")) {
|
||||||
|
return `${currentDomain}/quay`;
|
||||||
|
} else if (imageInput.startsWith("ghcr.io/")) {
|
||||||
|
return `${currentDomain}/ghcr`;
|
||||||
|
} else {
|
||||||
|
return currentDomain;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getImageNameFromInput(imageInput, source) {
|
||||||
|
if (imageInput.startsWith("gcr.io/")) {
|
||||||
|
return imageInput.replace("gcr.io/", "");
|
||||||
|
} else if (imageInput.startsWith("k8s.gcr.io/")) {
|
||||||
|
return imageInput.replace("k8s.gcr.io/", "");
|
||||||
|
} else if (imageInput.startsWith("quay.io/")) {
|
||||||
|
return imageInput.replace("quay.io/", "");
|
||||||
|
} else if (imageInput.startsWith("ghcr.io/")) {
|
||||||
|
return imageInput.replace("ghcr.io/", "");
|
||||||
|
} else {
|
||||||
|
return imageInput;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function copyToClipboard(elementId) {
|
||||||
|
const copyText = document.getElementById(elementId);
|
||||||
|
copyText.select();
|
||||||
|
copyText.setSelectionRange(0, 99999); // For mobile devices
|
||||||
|
document.execCommand('copy');
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
Loading…
x
Reference in New Issue
Block a user