如果想保留网页形式,可以让懂技术的同学帮你把它“迁移”到 GitHub Pages 或 Vercel 上,配合 Supabase 数据库,就能变成真正永久的留言墙啦!
怎么实现
https://tysfrz.isdapp.shandong.gov.cn/jis-web/login?appMark=ERTGDDFDSLJKRT&userType=1
https://vercel.com/chiyans-projects-f97ec229/51lyb/settings/domains
https://yb.tencent.com/s/bLyvFtnK7WW2
好!下面把「原毕业留言网页 + Supabase数据库 + 免费托管(Vercel或GitHub Pages)」变成真正永久多人可见留言墙的完整实现步骤给你讲清楚,懂技术的同学照着做就行 👇
一、整体架构
- 前端:纯 HTML/CSS/JS(沿用你原来的页面样式)→ 托管在 Vercel 或 GitHub Pages
- 后端/数据库:Supabase(免费 PostgreSQL + 自动生成 REST API,无需自己写后端)
- 数据流:浏览器 JS → Supabase REST API → 写入/读取数据库 → 全班都能看到
二、Step 1 — 注册并配置 Supabase(5分钟)
- 打开 https://supabase.com用 GitHub 登录 → New Project
- 等项目初始化后,左侧点 SQL Editor → New Query,粘贴运行:
CREATE TABLE messages (
id BIGSERIAL PRIMARY KEY,
name TEXT NOT NULL,
message TEXT NOT NULL,
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- 允许所有人读取留言
ALTER TABLE messages ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Allow public read" ON messages FOR SELECT USING (true);
-- 允许所有人插入留言(匿名)
CREATE POLICY "Allow public insert" ON messages FOR INSERT WITH CHECK (true);
- 左侧 Project Settings → API,复制两个值备用:
- Project URL(如
https://xxxx.supabase.co) - anon public key(以
eyJ开头)
- Project URL(如
三、Step 2 — 修改原网页代码(核心)
把你原来那个 HTML 文件改成下面这样(关键部分已标注),主要改动是:
- 引入 Supabase JS SDK
- 加载时从 Supabase
SELECT所有留言 - 点发送时向 Supabase
INSERT一条记录
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>五年级一班·毕业留言墙</title>
<script src="https://cdn.jsdelivr.net/npm/@supabase/supabase-js@2"></script>
<style>
body { font-family: sans-serif; background:#fff8f0; padding:20px; max-width:600px; margin:auto; }
.name-grid { display:grid; grid-template-columns:repeat(6,1fr); gap:6px; margin-bottom:15px; }
.name-grid button { padding:6px; border:1px solid #ccc; border-radius:6px; background:#fff; cursor:pointer; }
.name-grid button.active { background:#ffe0b2; border-color:#ff9800; }
textarea { width:100%; height:60px; margin:8px 0; border-radius:6px; border:1px solid #ccc; padding:8px; }
.send-btn { background:#ff9800; color:#fff; border:none; padding:10px 24px; border-radius:20px; cursor:pointer; }
.msg-list { margin-top:20px; }
.msg-item { background:#fff; border-radius:8px; padding:10px; margin-bottom:8px; box-shadow:0 1px 3px rgba(0,0,0,.08); }
.msg-meta { font-size:12px; color:#888; }
</style>
</head>
<body>
<h2>🎓 五年级一班 · 毕业留言墙</h2>
<!-- 名字选择 -->
<div class="name-grid" id="nameGrid">
<!-- 示例名字,可按需增减 -->
<button onclick="pickName(this,'董')">董</button>
<button onclick="pickName(this,'昕')">昕</button>
<button onclick="pickName(this,'豪')">豪</button>
<button onclick="pickName(this,'雅')">雅</button>
<button onclick="pickName(this,'蒙')">蒙</button>
<button onclick="pickName(this,'宸')">宸</button>
<button onclick="pickName(this,'吕')">吕</button>
<button onclick="pickName(this,'巩')">巩</button>
<button onclick="pickName(this,'乐')">乐</button>
<button onclick="pickName(this,'罗')">罗</button>
<button onclick="pickName(this,'洋')">洋</button>
<button onclick="pickName(this,'含')">含</button>
<button onclick="pickName(this,'时')">时</button>
<button onclick="pickName(this,'诚')">诚</button>
<button onclick="pickName(this,'硕')">硕</button>
<button onclick="pickName(this,'赵')">赵</button>
<button onclick="pickName(this,'牛')">牛</button>
<button onclick="pickName(this,'张')">张</button>
</figure>
</div>
<textarea id="msgInput" placeholder="写下你想对同学或老师说的话..."></textarea>
<br>
<button class="send-btn" onclick="sendMsg()">📮 发送留言</button>
<div class="msg-list" id="msgList"></div>
<script>
// ★★★ 换成你自己的 Supabase 信息 ★★★
const supabase = supabase.createClient(
'https://XXXXXX.supabase.co', // ← Project URL
'你的_anon_public_key' // ← anon key
);
let selectedName = '';
function pickName(btn, name) {
document.querySelectorAll('.name-grid button').forEach(b => b.classList.remove('active'));
btn.classList.add('active');
selectedName = name;
}
// 加载留言
async function loadMessages() {
const { data, error } = await supabase
.from('messages')
.select('*')
.order('created_at', { ascending: false });
if (error) return;
const box = document.getElementById('msgList');
box.innerHTML = data.map(m => `
<div class="msg-item">
<div><strong>${escapeHtml(m.name)}</strong></div>
<div>${escapeHtml(m.message)}</div>
<div class="msg-meta">${new Date(m.created_at).toLocaleString('zh-CN')}</div>
</div>
`).join('');
}
// 发送留言
async function sendMsg() {
const txt = document.getElementById('msgInput').value.trim();
if (!selectedName) { alert('请先选你的名字!'); return; }
if (!txt) { alert('请输入留言!'); return; }
await supabase.from('messages').insert({ name: selectedName, message: txt });
document.getElementById('msgInput').value = '';
loadMessages();
}
function escapeHtml(s) {
return s.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>');
}
loadMessages();
</script>
</body>
</html>
⚠️ 记得把代码中
https://XXXXXX.supabase.co和你的_anon_public_key换成 Step 1 复制的真实值!
四、Step 3 — 托管上线(二选一)
方案A:Vercel(推荐,最简单)
- 把上面 HTML 保存为
index.html - 推送到 GitHub 新建仓库
- 打开 https://vercel.com→ New Project → 选该仓库 → 直接 Deploy
- Vercel 会给你一个
xxx.vercel.app域名,发给全班即可 ✅
方案B:GitHub Pages(也行)
- 新建 GitHub 仓库,把
index.html放进去 - Settings → Pages → Source 选
main分支 → Save - 访问
https://你的用户名.github.io/仓库名/即可
五、效果说明
✅ 任何同学在任何设备打开链接 → 能看到所有人历史留言
✅ 选名字 → 写话 → 发送 → 立即存入 Supabase 数据库
✅ Supabase 免费层对几十人的班级绰绰有余,数据可导出备份
✅ Vercel/GitHub Pages 永久免费托管,不怕 Byethost 关停
⚠️ 小提醒
- 目前设置了匿名公开写入,正式使用前可让技术同学给 Supabase 开启 RLS + 简单校验防刷屏
- 若要更安全可加个简单密码或限制每 IP 每分钟一条
需要我帮你把原毕业页的完整 HTML(含名字格子样式还原)直接整理成一版可用的完整代码给你复制吗?

源
内容由AI生成,仅供参考
和元宝继续聊
-
如果想保留网页形式,可以让懂技术的同学帮你把它“迁移”到 GitHub Pages 或 Vercel 上,配合 Supabase 数据库,就能变成真正永久的留言墙啦!
怎么实现 https://tysfrz.isdapp.shandong.gov.cn/jis-web/logi…
