354 lines
11 KiB
HTML
354 lines
11 KiB
HTML
![]() |
<!DOCTYPE html>
|
||
|
<html lang="zh-CN">
|
||
|
<head>
|
||
|
<meta charset="UTF-8">
|
||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
|
<title>服务器错误 - <span id="error-code">500</span></title>
|
||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
||
|
<style>
|
||
|
* {
|
||
|
margin: 0;
|
||
|
padding: 0;
|
||
|
box-sizing: border-box;
|
||
|
}
|
||
|
|
||
|
body {
|
||
|
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||
|
background: linear-gradient(135deg, #ff6b6b 0%, #cc2b5e 100%);
|
||
|
color: #fff;
|
||
|
min-height: 100vh;
|
||
|
display: flex;
|
||
|
flex-direction: column;
|
||
|
justify-content: center;
|
||
|
align-items: center;
|
||
|
text-align: center;
|
||
|
padding: 20px;
|
||
|
}
|
||
|
|
||
|
.container {
|
||
|
max-width: 900px;
|
||
|
width: 100%;
|
||
|
background: rgba(255, 255, 255, 0.1);
|
||
|
backdrop-filter: blur(10px);
|
||
|
border-radius: 20px;
|
||
|
padding: 40px;
|
||
|
box-shadow: 0 15px 35px rgba(0, 0, 0, 0.2);
|
||
|
border: 1px solid rgba(255, 255, 255, 0.2);
|
||
|
}
|
||
|
|
||
|
.error-code {
|
||
|
font-size: 120px;
|
||
|
font-weight: 800;
|
||
|
margin-bottom: 10px;
|
||
|
text-shadow: 3px 3px 0 rgba(0, 0, 0, 0.2);
|
||
|
color: #fff;
|
||
|
line-height: 1;
|
||
|
animation: pulse 2s infinite;
|
||
|
}
|
||
|
|
||
|
.error-title {
|
||
|
font-size: 32px;
|
||
|
margin-bottom: 15px;
|
||
|
color: #fff;
|
||
|
}
|
||
|
|
||
|
.error-description {
|
||
|
font-size: 18px;
|
||
|
margin-bottom: 25px;
|
||
|
padding: 15px;
|
||
|
background: rgba(0, 0, 0, 0.2);
|
||
|
border-radius: 10px;
|
||
|
line-height: 1.6;
|
||
|
}
|
||
|
|
||
|
.error-message {
|
||
|
font-size: 16px;
|
||
|
margin-bottom: 30px;
|
||
|
line-height: 1.6;
|
||
|
color: rgba(255, 255, 255, 0.9);
|
||
|
}
|
||
|
|
||
|
.server-status {
|
||
|
background: rgba(0, 0, 0, 0.2);
|
||
|
border-radius: 10px;
|
||
|
padding: 20px;
|
||
|
margin: 20px 0;
|
||
|
text-align: left;
|
||
|
}
|
||
|
|
||
|
.status-title {
|
||
|
font-size: 18px;
|
||
|
margin-bottom: 15px;
|
||
|
display: flex;
|
||
|
align-items: center;
|
||
|
}
|
||
|
|
||
|
.status-title i {
|
||
|
margin-right: 10px;
|
||
|
}
|
||
|
|
||
|
.status-item {
|
||
|
display: flex;
|
||
|
justify-content: space-between;
|
||
|
padding: 8px 0;
|
||
|
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
|
||
|
}
|
||
|
|
||
|
.status-label {
|
||
|
font-weight: 500;
|
||
|
}
|
||
|
|
||
|
.status-value {
|
||
|
font-weight: 600;
|
||
|
}
|
||
|
|
||
|
.status-value.down {
|
||
|
color: #ff6b6b;
|
||
|
}
|
||
|
|
||
|
.status-value.up {
|
||
|
color: #4CAF50;
|
||
|
}
|
||
|
|
||
|
.action-buttons {
|
||
|
display: flex;
|
||
|
justify-content: center;
|
||
|
gap: 15px;
|
||
|
flex-wrap: wrap;
|
||
|
margin: 30px 0;
|
||
|
}
|
||
|
|
||
|
.btn {
|
||
|
padding: 12px 25px;
|
||
|
background: rgba(255, 255, 255, 0.2);
|
||
|
color: white;
|
||
|
text-decoration: none;
|
||
|
border-radius: 50px;
|
||
|
transition: all 0.3s;
|
||
|
border: 1px solid rgba(255, 255, 255, 0.3);
|
||
|
display: flex;
|
||
|
align-items: center;
|
||
|
}
|
||
|
|
||
|
.btn i {
|
||
|
margin-right: 8px;
|
||
|
}
|
||
|
|
||
|
.btn:hover {
|
||
|
background: rgba(255, 255, 255, 0.3);
|
||
|
transform: translateY(-3px);
|
||
|
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
|
||
|
}
|
||
|
|
||
|
.countdown {
|
||
|
font-size: 16px;
|
||
|
margin-top: 20px;
|
||
|
padding: 10px;
|
||
|
background: rgba(0, 0, 0, 0.2);
|
||
|
border-radius: 10px;
|
||
|
}
|
||
|
|
||
|
.countdown-number {
|
||
|
font-weight: 700;
|
||
|
color: #FFD700;
|
||
|
}
|
||
|
|
||
|
.error-details {
|
||
|
margin-top: 20px;
|
||
|
padding: 15px;
|
||
|
background: rgba(0, 0, 0, 0.1);
|
||
|
border-radius: 8px;
|
||
|
text-align: left;
|
||
|
font-size: 14px;
|
||
|
}
|
||
|
|
||
|
.nginx-brand {
|
||
|
margin-top: 40px;
|
||
|
opacity: 0.7;
|
||
|
font-size: 14px;
|
||
|
display: flex;
|
||
|
align-items: center;
|
||
|
justify-content: center;
|
||
|
}
|
||
|
|
||
|
/* 动画效果 */
|
||
|
@keyframes pulse {
|
||
|
0% { transform: scale(1); }
|
||
|
50% { transform: scale(1.05); }
|
||
|
100% { transform: scale(1); }
|
||
|
}
|
||
|
|
||
|
@keyframes spin {
|
||
|
0% { transform: rotate(0deg); }
|
||
|
100% { transform: rotate(360deg); }
|
||
|
}
|
||
|
|
||
|
.fa-spinner {
|
||
|
animation: spin 1.5s linear infinite;
|
||
|
}
|
||
|
|
||
|
/* 响应式设计 */
|
||
|
@media (max-width: 600px) {
|
||
|
.error-code {
|
||
|
font-size: 80px;
|
||
|
}
|
||
|
|
||
|
.error-title {
|
||
|
font-size: 24px;
|
||
|
}
|
||
|
|
||
|
.error-description, .error-message {
|
||
|
font-size: 16px;
|
||
|
}
|
||
|
|
||
|
.container {
|
||
|
padding: 30px 20px;
|
||
|
}
|
||
|
|
||
|
.action-buttons {
|
||
|
flex-direction: column;
|
||
|
}
|
||
|
|
||
|
.btn {
|
||
|
justify-content: center;
|
||
|
}
|
||
|
}
|
||
|
</style>
|
||
|
</head>
|
||
|
<body>
|
||
|
<div class="container">
|
||
|
<h1 class="error-code" id="dynamic-error-code">500</h1>
|
||
|
<h2 class="error-title" id="error-title">服务器内部错误</h2>
|
||
|
|
||
|
<div class="error-description" id="error-description">
|
||
|
服务器遇到了意外的条件,无法完成您的请求。
|
||
|
</div>
|
||
|
|
||
|
<p class="error-message">
|
||
|
我们的技术团队已收到通知,正在努力解决问题。<br>
|
||
|
请稍后再试或联系技术支持获取帮助。
|
||
|
</p>
|
||
|
|
||
|
<div class="server-status">
|
||
|
<div class="status-title">
|
||
|
<i class="fas fa-server"></i>
|
||
|
<span>服务器状态监控</span>
|
||
|
</div>
|
||
|
<div class="status-item">
|
||
|
<span class="status-label">Web服务器</span>
|
||
|
<span class="status-value up">运行正常 <i class="fas fa-check-circle"></i></span>
|
||
|
</div>
|
||
|
<div class="status-item">
|
||
|
<span class="status-label">应用程序服务</span>
|
||
|
<span class="status-value down" id="app-status">遇到问题 <i class="fas fa-exclamation-circle"></i></span>
|
||
|
</div>
|
||
|
<div class="status-item">
|
||
|
<span class="status-label">数据库连接</span>
|
||
|
<span class="status-value up">连接正常 <i class="fas fa-check-circle"></i></span>
|
||
|
</div>
|
||
|
<div class="status-item">
|
||
|
<span class="status-label">错误发生时间</span>
|
||
|
<span class="status-value" id="current-time"></span>
|
||
|
</div>
|
||
|
</div>
|
||
|
|
||
|
<div class="action-buttons">
|
||
|
<a href="/" class="btn">
|
||
|
<i class="fas fa-home"></i>
|
||
|
<span>返回首页</span>
|
||
|
</a>
|
||
|
<a href="javascript:location.reload()" class="btn">
|
||
|
<i class="fas fa-redo"></i>
|
||
|
<span>重新加载</span>
|
||
|
</a>
|
||
|
<a href="javascript:history.back()" class="btn">
|
||
|
<i class="fas fa-arrow-left"></i>
|
||
|
<span>返回上一页</span>
|
||
|
</a>
|
||
|
<a href="/contact" class="btn">
|
||
|
<i class="fas fa-envelope"></i>
|
||
|
<span>联系支持</span>
|
||
|
</a>
|
||
|
</div>
|
||
|
|
||
|
<div class="countdown">
|
||
|
<p>页面将在 <span class="countdown-number" id="countdown">15</span> 秒后自动重新加载 <i class="fas fa-spinner"></i></p>
|
||
|
</div>
|
||
|
|
||
|
<div class="error-details">
|
||
|
<p><strong>技术信息:</strong></p>
|
||
|
<p>错误代码: <span id="technical-error-code">500</span></p>
|
||
|
<p>请求ID: <span id="request-id">REQ-${Math.random().toString(36).substr(2, 9).toUpperCase()}</span></p>
|
||
|
<p>服务器: <span id="server-name">${window.location.hostname}</span></p>
|
||
|
</div>
|
||
|
|
||
|
<div class="nginx-brand">
|
||
|
<span>Powered by Nginx</span>
|
||
|
</div>
|
||
|
</div>
|
||
|
|
||
|
<script>
|
||
|
function getErrorCodeFromURL() {
|
||
|
const urlParams = new URLSearchParams(window.location.search);
|
||
|
return urlParams.get('error') || '500';
|
||
|
}
|
||
|
|
||
|
const errorDescriptions = {
|
||
|
'500': {
|
||
|
title: '服务器内部错误',
|
||
|
description: '服务器遇到了意外的条件,无法完成您的请求。这通常是服务器端代码的问题。'
|
||
|
},
|
||
|
'502': {
|
||
|
title: '错误的网关',
|
||
|
description: '服务器作为网关或代理,从上游服务器收到无效响应。这可能是后端服务无响应或配置错误。'
|
||
|
},
|
||
|
'503': {
|
||
|
title: '服务不可用',
|
||
|
description: '服务器暂时无法处理请求,通常是由于过载或维护。请稍后再试。'
|
||
|
},
|
||
|
'504': {
|
||
|
title: '网关超时',
|
||
|
description: '服务器作为网关或代理,没有及时从上游服务器收到响应。这可能是网络问题或后端服务响应缓慢。'
|
||
|
}
|
||
|
};
|
||
|
|
||
|
function setupErrorPage() {
|
||
|
const errorCode = getErrorCodeFromURL();
|
||
|
const errorInfo = errorDescriptions[errorCode] || errorDescriptions['500'];
|
||
|
|
||
|
document.getElementById('dynamic-error-code').textContent = errorCode;
|
||
|
document.getElementById('error-title').textContent = errorInfo.title;
|
||
|
document.getElementById('error-description').textContent = errorInfo.description;
|
||
|
document.title = `服务器错误 - ${errorCode}`;
|
||
|
document.getElementById('technical-error-code').textContent = errorCode;
|
||
|
}
|
||
|
|
||
|
let seconds = 15;
|
||
|
const countdownElement = document.getElementById('countdown');
|
||
|
|
||
|
const countdown = setInterval(function() {
|
||
|
seconds--;
|
||
|
countdownElement.textContent = seconds;
|
||
|
|
||
|
if (seconds <= 0) {
|
||
|
clearInterval(countdown);
|
||
|
window.location.reload();
|
||
|
}
|
||
|
}, 1000);
|
||
|
|
||
|
function updateCurrentTime() {
|
||
|
const now = new Date();
|
||
|
const timeElement = document.getElementById('current-time');
|
||
|
timeElement.textContent = now.toLocaleString();
|
||
|
}
|
||
|
|
||
|
document.addEventListener('DOMContentLoaded', function() {
|
||
|
setupErrorPage();
|
||
|
updateCurrentTime();
|
||
|
setInterval(updateCurrentTime, 1000);
|
||
|
document.getElementById('server-name').textContent = window.location.hostname;
|
||
|
});
|
||
|
|
||
|
</script>
|
||
|
</body>
|
||
|
</html>
|