当网站后端暂时无法访问时,可以让 Nginx 自动显示一个静态备用页面,提示用户检查网络,并提供售后信息。
一、准备文件
将以下两个文件上传到宝塔网站根目录:
/www/wwwroot/test.zhangsan.cool/offline.html /www/wwwroot/test.zhangsan.cool/sw.js文件说明(供参考,具体自行修改):
offline.html:网站无法访问时显示的备用页面。
<!doctype html><htmllang="zh-CN"><head><metacharset="utf-8"><metaname="viewport"content="width=device-width, initial-scale=1, viewport-fit=cover"><metaname="theme-color"content="#f5f7fb"><metaname="description"content="网站备用入口和联系方式。"><title>网站暂时无法访问|备用入口</title><style>:root{color-scheme: light;--ink:#182235; --muted:#687386; --blue:#2563eb; --line:#e2e7f0; --surface:#fff; }*{box-sizing:border-box;}html, body{margin:0;min-height:100%;}body{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI","PingFang SC","Microsoft YaHei",Arial,sans-serif;color:var(--ink);background:#f5f7fb; }.shell{min-height:100vh;padding:24px 16px calc(28px + env(safe-area-inset-bottom));display:flex;align-items:center;justify-content:center;}.page{width:min(100%,620px);}.card{background:var(--surface);border:1px solid var(--line);border-radius:18px;padding:28px 20px 22px;box-shadow:0 12px 35px rgba(30,45,75,.07);}h1{margin:0;font-size:clamp(28px,7vw,42px);line-height:1.2;letter-spacing:-.03em;}.status{display:inline-flex;align-items:center;gap:7px;margin-bottom:14px;color:#a16207; font-size:13px; font-weight:700; }.status-dot{width:8px;height:8px;border-radius:50%;background:#eab308; box-shadow:0 0 0 4px #fef3c7; }.intro{margin:10px022px;color:var(--muted);font-size:15px;line-height:1.65;}.nav-link{display:flex;align-items:center;justify-content:center;gap:9px;min-height:54px;padding:14px 18px;border-radius:12px;color:#fff; background:var(--blue); text-decoration:none; font-size:17px; font-weight:700; box-shadow:0 8px 16px rgba(37,99,235,.2); }.nav-link:hover, .nav-link:focus-visible{background:#1d4ed8; }.nav-link svg{width:19px;height:19px;}.section-title{margin:26px010px;font-size:17px;}.contacts{display:grid;gap:10px;}.contact{display:flex;align-items:center;gap:12px;min-width:0;padding:14px;border:1px solid var(--line);border-radius:12px;}.contact-icon{flex:0036px;width:36px;height:36px;display:grid;place-items:center;border-radius:10px;color:var(--blue);background:#eef4ff; }.contact-icon svg{width:20px;height:20px;}.contact-copy{flex:1;min-width:0;}.label{margin:003px;color:var(--muted);font-size:13px;}.value{margin:0;font-size:19px;font-weight:700;overflow-wrap:anywhere;}.copy{flex:00auto;min-height:40px;padding:0 14px;border:1px solid#bfd2f6; border-radius:9px; color:var(--blue); background:#fff; font:inherit; font-size:14px; font-weight:700; cursor:pointer; }.copy:hover, .copy:focus-visible{background:#eef4ff; }.copy.copied{border-color:#b7dfc9; color:#147a4b; background:#edf9f2; }.contact--featured{border-color:#bfd2f6; background:#f8fbff; }:is(.nav-link, .copy):focus-visible{outline:3px solid rgba(37,99,235,.28);outline-offset:3px;}.note{margin:18px00;color:#8a94a5; font-size:12px; line-height:1.6; text-align:center; }.toast{position:fixed;left:50%;bottom:calc(22px + env(safe-area-inset-bottom));transform:translate(-50%,16px);opacity:0;pointer-events:none;padding:9px 13px;border-radius:9px;color:#fff; background:#1d293d; font-size:13px; transition:opacity .18s,transform .18s; }.toast.show{opacity:1;transform:translate(-50%,0);}@media(max-width:599px){.shell{padding:14px 12px calc(20px + env(safe-area-inset-bottom));}.card{padding:18px 14px 22px;border-radius:15px;}.intro{margin-bottom:18px;}.section-title{margin-top:22px;}}@media(min-width:760px){.card{padding:40px 42px 30px;}.contacts{grid-template-columns:1fr 1fr;}}@media(prefers-reduced-motion: reduce){.toast{transition:none;}}</style></head><body><mainclass="shell"><sectionclass="page card"aria-labelledby="title"><divclass="status"><spanclass="status-dot"aria-hidden="true"></span>当前连接可能不稳定</div><h1id="title">网站暂时无法访问</h1><pclass="intro">请先检查网络连接并刷新页面;如果仍无法访问,可通过下方联系方式获取帮助。</p><aclass="nav-link"href="https://vlink.cc/uu5wok0k"target="_blank"rel="noopener noreferrer">打开最新网址<svgviewBox="0 0 24 24"fill="none"stroke="currentColor"stroke-width="2"aria-hidden="true"><pathd="M14 5h5v5M19 5l-8 8"/><pathd="M18 13v5a1 1 0 0 1-1 1H6a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h5"/></svg></a><h2class="section-title">备用联系方式</h2><divclass="contacts"><divclass="contact contact--featured"><spanclass="contact-icon"aria-hidden="true"><svgviewBox="0 0 24 24"fill="none"stroke="currentColor"stroke-width="2"><pathd="M7 7h10v8H7z"/><pathd="M7 10H4v5h3M17 10h3v5h-3M9 18h6M12 15v3"/></svg></span><divclass="contact-copy"><pclass="label">售后QQ群 · 进群获取最新资讯</p><pclass="value">815440815</p></div><buttonclass="copy"type="button">="815440815">="复制"aria-label="复制QQ群号 815440815">复制</button></div><divclass="contact"><spanclass="contact-icon"aria-hidden="true"><svgviewBox="0 0 24 24"fill="none"stroke="currentColor"stroke-width="2"><pathd="M20 11.5a7.5 7.5 0 0 1-11.8 6.1L4 19l1.5-3.9A7.5 7.5 0 1 1 20 11.5Z"/><pathd="M9 10.5c.6 1.3 1.7 2.4 3 3l1-.8 1.5.7-.3 1.3c-.2.6-.8.8-1.4.6a8.3 8.3 0 0 1-5.1-5.1c-.2-.6 0-1.2.6-1.4l1.3-.3.7 1.5-.8 1Z"/></svg></span><divclass="contact-copy"><pclass="label">售后微信</p><pclass="value">15682448658</p></div><buttonclass="copy"type="button">="15682448658">="复制"aria-label="复制售后微信号 15682448658">复制</button></div></div><pclass="note">建议收藏本页,方便下次快速找到入口。</p></section></main><divclass="toast"role="status"aria-live="polite"></div><script>(()=>{ const toast=document.querySelector('.toast');let timer;const show=(message)=>{ toast.textContent=message;toast.classList.add('show');clearTimeout(timer);timer=setTimeout(()=>toast.classList.remove('show'),1800);};const fallbackCopy=(text)=>{ const area=document.createElement('textarea');area.value=text;area.setAttribute('readonly','');area.style.position='fixed';area.style.opacity='0';document.body.appendChild(area);area.select();const ok=document.execCommand('copy');area.remove();return ok;};document.querySelectorAll('[data-copy]').forEach((button)=>button.addEventListener('click',async()=>{ const text=button.dataset.copy;try { if(navigator.clipboard&&window.isSecureContext)await navigator.clipboard.writeText(text);else if(!fallbackCopy(text))throw new Error('copy failed');button.textContent='已复制 ✓';button.classList.add('copied');clearTimeout(button._resetTimer);button._resetTimer=setTimeout(()=>{ button.textContent=button.dataset.defaultLabel;button.classList.remove('copied');},1800);show('已复制:'+text);} catch { show('复制失败,请手动复制');} }));})();</script><script>if('serviceWorker'innavigator){window.addEventListener('load',()=>{navigator.serviceWorker.register('/sw.js',{scope:'/'}).then((registration)=>{ console.log('Service Worker 注册成功:',registration.scope);return registration.update();}).catch((error)=>console.error('Service Worker 注册失败:',error));});}else{console.warn('当前浏览器不支持 Service Worker');}</script></body></html>sw.js:负责缓存备用页面,并在断网时返回缓存内容。
const CACHE_NAME='offline-contact-v5';const OFFLINE_URL='/offline.html';self.addEventListener('install',(event)=>{event.waitUntil(caches.open(CACHE_NAME).then((cache)=>cache.add(OFFLINE_URL)));self.skipWaiting();});self.addEventListener('activate',(event)=>{event.waitUntil(caches.keys().then((keys)=>Promise.all(keys.filter((key)=>key!==CACHE_NAME).map((key)=>caches.delete(key)))));self.clients.claim();});self.addEventListener('fetch',(event)=>{const url=new URL(event.request.url);if(event.request.method!=='GET'||event.request.mode!=='navigate'||url.origin!==self.location.origin||url.pathname.startsWith('/service-api/'))return;event.respondWith(fetch(event.request).then((response)=>{ if(![502,503,504].includes(response.status))returnresponse;returncaches.match(OFFLINE_URL).then((cached)=>cached||response);}).catch(()=>caches.match(OFFLINE_URL).then((cached)=>cached||Response.error())));});二、配置 HTTPS
Service Worker 必须运行在 HTTPS 环境下。
在宝塔中进入:
网站 → 你的域名 → SSL申请并启用 SSL,之后使用下面的地址访问网站:
https://你的域名/不要使用普通 HTTP 或服务器 IP 地址测试。
三、添加宝塔自定义配置
进入:
网站 → 你的域名 → 配置文件 → 自定义配置文件不要修改“主配置文件”,将下面完整内容粘贴到“自定义配置文件”中:
location = /sw.js { root /www/wwwroot/test.zhangsan.cool; default_type application/javascript; add_header Cache-Control "no-cache" always; add_header Service-Worker-Allowed "/" always; try_files $uri =404; } location = /offline.html { root /www/wwwroot/test.zhangsan.cool; default_type text/html; add_header Cache-Control "no-cache" always; try_files $uri =404; } error_page 502 503 504 =200 /offline.html; proxy_set_header Accept-Encoding ""; sub_filter_types text/html; sub_filter_once on; sub_filter '</body>' '<script>if("serviceWorker" in navigator){window.addEventListener("load",function(){navigator.serviceWorker.register("/sw.js",{scope:"/"}).then(function(r){console.log("Service Worker 注册成功",r.scope);return r.update();}).catch(function(e){console.error("Service Worker 注册失败",e);});});}</script></body>';其中反向代理后端使用本机地址:
127.0.0.1:8080如果宝塔已经自动生成了反向代理配置,不要重复添加第二个location ^~ /,只添加上面的自定义内容即可。
四、修改页面后更新缓存
编辑修改offline.html或sw.js后,需要修改sw.js中的缓存版本号,例如:
constCACHE_NAME='offline-contact-v4';然后重新上传文件,联网刷新页面,再测试断网。