DragonRster`s Void
Banner Image
Hi!

. 欢迎来到这个还在建设中的无厘头网站。我正在重拾对老式网页和HTML的热爱,并在摸索中不断尝试。

. 这个网站将会建成一个纯HTML的90s风格的个人博客,适配1024x768分辨率,兼容IE5.5+,并且可以正常在Windows 95上访问。

. 目前这个网站还在建设,很多内容都在完善中!。。

留言板

icuqALT10:
阿尔艾斯我喜欢你 120.9.125.210
2026-04-27 18:14:31

Shining_Growth:
如果更新了背景音乐功能,我一定要来听一整天《初恋》 -u- (被二创种草后意外的很喜欢这种风格的音乐) 117.179.94.61
2026-04-26 23:57:53

Sublime:
我去牛逼 122.195.38.14
2026-04-26 23:39:58

DragonRSTER:
嘿,现在支持填写邮箱了,点击ID即可跳转邮箱
2026-04-26 18:52:27

666:
666 61.169.203.218
2026-03-25 11:19:53

xintai:
This message was sent from win98 180.154.121.226
2026-04-24 23:33:41

DragonRSTER:
@asdafga haha
2026-04-05 10:00:00

asdafga:
都6202年了,你还在用纯HTML,我觉得你可以去申请文化遗产了
2026-03-05 09:28:44

DragonRSTER:
@pixel_dream 新年快乐
2026-01-01 00:25:55

pixel_dream:
RS新年快乐~
2026-01-01 00:10:30

DragonRSTER:
@pornhub LTO+1
2025-03-21 19:05:16

pornhub:
赛博仓鼠症同好,最近在考虑LTO磁带机 185.66.90.77
2025-03-21 18:30:50

DragonRSTER:
@lattice_work 感谢提醒
2025-02-04 10:45:30

lattice_work:
8831按钮里面Operation链接失效了
2025-02-04 09:11:22

DragonRSTER:
@mania 懒。。。
2025-01-25 17:20:49

mania:
你的博客最近没更新啊
2025-01-25 16:08:02

DragonRSTER:
@crt_king 忘记了,我打包发你邮箱吧
2024-11-08 15:03:44

crt_king:
rs 86box里你用的什么主板? 61.172.95.34
2024-11-08 14:42:11

DragonRSTER:
@pixel_dream 中秋快乐
2024-09-30 00:02:33

pixel_dream:
RS 中秋快乐!
2024-09-17 23:15:45

留言板架构记录

纯文本存储 + CGI 处理


整体流程

留言提交后的完整路径如下:


  [访客填写表单]  →  [CGI 脚本接收]  →  [写入 guestbook.txt]
         ↓
  [触发 rebuild-all]  →  [build.ps1 读取数据]  →  [注入侧边栏 HTML]
         ↓
  [部署新页面]  →  [访客看到留言]
            

留言后不会实时出现,而是在下一次构建时被编译进静态页面里(感觉有必要做个实时更新)。

1. 前端表单

表单直接写在 sidebar-left.html 里,位于左侧栏留言板区域。一个标准的 HTML 3.2 表单:


<form action="/cgi-bin/guestbook.py" method="post">
    Name:    <input type="text" name="name">
    Email:   <input type="text" name="email" placeholder="Optional">
    内容:    <textarea name="content"></textarea>
    [x] 显示IP  <input type="checkbox" name="show_ip" value="yes">
    <input type="submit" value="发送留言">
</form>
            

四个字段:name(必填)、email(可选,填写后用户名会变成 mailto 链接)、content(必填)、show_ip(控制是否公开展示 IP),没有验证码(暂时不考虑)

2. CGI 后端

触发留言后表单提交到 /cgi-bin/guestbook.py CGI 脚本处理。

输入处理


def parse_form_data():
    method = os.environ.get('REQUEST_METHOD', 'GET')
    if method == 'GET':
        qs = os.environ.get('QUERY_STRING', '')
        form_data = parse_qs(qs)
    else:
        length = int(os.environ.get('CONTENT_LENGTH', 0))
        body = sys.stdin.read(length)
        form_data = parse_qs(body)
    return {k: v[0] for k, v in form_data.items()}
            

CGI 的数据来源非常原始:GET 请求从 QUERY_STRING 环境变量读,POST 请求从标准输入读。脚本会解析 URL-encoded 表单数据,然后进行清理:


def sanitize(text):
    text = text.replace('\n', ' ').replace('\r', ' ')  # 移除换行
    text = text.replace('|', ' ')                       # 移除分隔符
    return html.escape(text)                            # 转义 HTML
            

移除 | 是因为它被用作数据文件的分隔符;移除换行防止数据格式被破坏;HTML 转义防止 XSS 攻击。

3. 客户端 IP 检测

因为部署在反向代理后面,直接读 REMOTE_ADDR 拿到的只会是代理服务器的 IP。所以 web_server.py 在每次请求时都会解析真实 IP,并通过环境变量传给 CGI:


# 在 CustomHandler._inject_real_ip() 中
cf_ip   = headers.get('CF-Connecting-IP')       # Cloudflare
xff     = headers.get('X-Forwarded-For')         # 标准代理头
real_ip = headers.get('X-Real-IP')               # Nginx 常用

if cf_ip:
    real_client_ip = cf_ip
elif xff:
    real_client_ip = xff.split(',')[0].strip()   # 取第一个
elif real_ip:
    real_client_ip = real_ip
else:
    real_client_ip = client_ip                    # 直连 fallback

os.environ["REAL_CLIENT_IP"] = real_client_ip     # 注入 CGI 环境
            

优先级:Cloudflare > X-Forwarded-For > X-Real-IP > 直连。CGI 脚本通过 os.environ.get("REAL_CLIENT_IP") 拿到正确的客户端 IP。

4. 数据存储

留言存储在 data/guestbook.txt,每行一条,字段用 | 分隔:


name|email|content|ip|time|show_ip    ← 新格式(6字段)
name|content|ip|time|show_ip          ← 旧格式(5字段,兼容)
            

示例:


DragonRSTER|dragonrster@foxmail.com|嘿,现在支持填写邮箱了|hidden|2026-04-26 18:52:27|no
xintai||This message was sent from win98|180.154.121.226|2026-04-24 23:33:41|yes
            

如果用户选择不显示 IP,IP 字段会写入 hidden 而不是真实地址。整个文件就是一个纯文本 CSV变体,可以用任何工具查看。目前积累了 30 多条留言,最早一条来自 2020年(上版博客的遗物)。

5. 构建时注入

每次执行 rebuild-all.ps1 时,build.ps1 会进行以下操作:


# 读取 guestbook.txt
$lines = Get-Content $guestbookFile -Encoding UTF8

# 取最后 20 条留言,反转顺序(最新在上)
$lastLines = $lines | Select-Object -Last 20
[array]::Reverse($lastLines)

# 逐条生成 HTML
foreach ($line in $lastLines) {
    $parts = $line -split '\|'
    # 兼容新旧两种格式...
    # 生成: 姓名(带 mailto) + 内容 + IP(可选) + 时间
}

# 注入到 sidebar-left.html 的占位符位置
$sidebarLeft = $sidebarLeft -replace "", $messagesHtml
            

留言内容被直接编译进 HTML,写在 sidebar-left.html<!-- GUESTBOOK_MESSAGES --> 占位符处。显示逻辑:

  • 有 email → 用户名渲染为 <a href="mailto:..."> 链接
  • show_ip 为 yes → 在留言下方显示 IP 地址(灰色小字)
  • 所有留言包在一个滚动容器内,最多显示 20 条
  • 因为 guestbook.txt 现在支持 email 字段,所以新旧格式会同时兼容,读取时根据字段数量自动判断。

    6. 服务器端

    web_server.py 继承自 Python 标准库的 CGIHTTPRequestHandler,在标准 CGI 支持之上加了几层自定义逻辑:

  • 路径映射:/index.html/blog-*dist//assets/*dist/assets/
  • 安全保护:/data//scripts//src/ 直接返回 403
  • CGI 目录:/cgi-bin/ 使用标准 CGI 处理流程
  • 日志记录:每次请求写入 data/logs/YYYY-MM-DD.log,旧日志自动 gzip 压缩
  • 启动方式:

    
    python web_server.py
    # 监听 0.0.0.0:81,默认端口 81
                
    7. 一些防御措施

    虽然纯人力,但还是做了一些基础限制:

  • 字段清理:移除 | 和换行符,防止数据格式注入
  • HTML 转义html.escape() 处理所有用户输入,防止 XSS
  • IP 可控:用户可以选择不公开 IP,写入 hidden 而非真实地址
  • 目录保护/data//scripts//src/ 从 HTTP 层直接 403
  • robots.txt:禁止爬虫访问 /cgi-bin//data/

  • 返回主页
    按钮

    返回主页

    最新文章

    » 留言板系统 · 从表...
    » 2026年4月 · ...
    » 盘龙阁·服务器
    » FnOS 漏洞链复现...
    » Wiki.js搭建说明

    » 文章归档

    更新日志

    2026-04-28
    优化侧边栏样式与截断逻辑

    2026-04-27
    右侧栏增加网站更新日志

    2026-04-27
    侧边栏增加最新文章列表、文章归档页

    2026-04-27
    全站博客正文统一宋体显示

    2026-04-27
    新增留言板架构博文

    2026-04-26
    服务器端增加日志记录与自动压缩

    2026-04-26
    留言板支持填写邮箱、点击ID可跳转

    2026-04-26
    新增 RSS 订阅源与 sitemap.xml

    2026-04-25
    重构项目结构,实现组件化模板系统

    2026-04-25
    首页改版,采用 HTML3.2 表格布局

    2026-04-25
    全新CGI 留言板功能上线(CGI + txt 存储)

    2026-04-05
    新增 Wiki.js 搭建说明博文

    2026-03-25
    新增 盘龙阁·服务器 介绍页

    2026-03-12
    新增 FnOS 漏洞链复现与提权博文

    2026-03-05
    新增老网站与资源收藏站点页面

    2026-02-28
    新增 Myrient 存档情况页面

    2026-02-10
    调整代码块样式,增加 khaki 配色

    2026-01-15
    修复留言板偶发提交失败的问题

    2026-01-01
    新年快乐!网站运行状态页面上线

    2025-12-24
    增加飘雪效果(圣诞节彩蛋)

    2025-12-01
    留言板增加 IP 归属地显示(已移除)

    2025-11-18
    修复移动端侧边栏错位问题

    2025-11-05
    新增 88x31 按钮收藏页面(归档 7589 枚)

    2025-10-22
    增加 HTTPS 支持

    2026-10-21
    网站框架搭建,适配 1024x768 / IE5.5

    2025-10-15
    博客从 ESP32-S3 迁移至云服务器


    DRAGONRSTER

    SSR订阅


    站点徽章

    © 2004-2026 DragonRster • Made with HTML • 本站支持IE5.5+
    最佳浏览分辨率:1024x768 • 最后更新于 2026年04月27日 23:48:34