学习总结笔记三:让网站“活”起来——处理静态文件、表单验证与用户登录(第3章实战版)

🎯 目标:让你的 ChitChat 留言板支持 CSS 样式、防止乱发帖,并实现简单的用户名登录!


✅ 1. 先解决"丑"的问题:加载 CSS 静态文件

现在你的留言板是纯文字,太朴素了。我们加个 CSS 让它好看点!

步骤一:创建静态资源目录
复制代码
chitchat/
├── main.go
├── templates/
│   └── index.html
└── static/               ← 新建这个文件夹
    └── style.css
步骤二:写个简单的 CSS(static/style.css)
css 复制代码
body {
  font-family: Arial, sans-serif;
  max-width: 600px;
  margin: 40px auto;
  padding: 20px;
  background: #f9f9f9;
}
input[type="text"] {
  width: 70%;
  padding: 8px;
}
button {
  padding: 8px 16px;
  background: #4CAF50;
  color: white;
  border: none;
  cursor: pointer;
}
p {
  background: white;
  padding: 10px;
  margin: 10px 0;
  border-left: 4px solid #4CAF50;
}
步骤三:在 HTML 中引用 CSS(templates/index.html 头部加一行)
html 复制代码
<head>
  <title>ChitChat 留言板</title>
  <link rel="stylesheet" href="/static/style.css"> <!-- 关键! -->
</head>
步骤四:让 Go 能"提供"静态文件

在 main.go 的 main() 函数里,加这一行:

go 复制代码
// 在 http.HandleFunc 之前加:
http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static/"))))

💡 这行代码的意思是:

  • 所有以 /static/ 开头的请求(比如 /static/style.css)
  • 去 static/ 文件夹里找对应文件并返回

✅ 现在重启服务,刷新页面------是不是变漂亮了?


✅ 2. 防止乱发帖:表单内容校验

用户可能提交空内容、超长内容,我们要拦截!

修改 post 函数:

go 复制代码
func post(w http.ResponseWriter, r *http.Request) {
	if r.Method != "POST" {
		http.Redirect(w, r, "/", http.StatusSeeOther)
		return
	}

	content := r.FormValue("content")
	content = strings.TrimSpace(content) // 去掉首尾空格

	// 校验规则
	if content == "" {
		http.Error(w, "留言不能为空!", http.StatusBadRequest)
		return
	}
	if len(content) > 200 {
		http.Error(w, "留言不能超过200个字!", http.StatusBadRequest)
		return
	}

	// 通过校验,才保存
	msg := Message{
		Content: content,
		Time:    time.Now().Format("2006-01-02 15:04"),
	}
	messages = append(messages, msg)
	http.Redirect(w, r, "/", http.StatusSeeOther)
}

别忘了在文件顶部导入 strings 包:

go 复制代码
import (
	...
	"strings"
)

🔍 测试:

  • 提交空内容 → 显示错误提示
  • 输入 300 个字 → 拒绝提交

我们不想每次发帖都输名字,那就让用户首次输入名字后记住他!

步骤一:首页加一个"登录"表单(只在没登录时显示)

修改 templates/index.html:

html 复制代码
{{if not .User}}
  <div style="margin-bottom:20px;">
    <form method="POST" action="/login">
      <input type="text" name="username" placeholder="输入你的昵称" required>
      <button type="submit">进入聊天室</button>
    </form>
  </div>
{{else}}
  <h2>你好,{{.User}}!</h2>
  <form method="POST" action="/post">
    <input type="text" name="content" placeholder="写下你想说的..." required>
    <button type="submit">发送</button>
  </form>
{{end}}

注意:模板里用了 {``{if not .User}} 判断是否已登录。

go 复制代码
func home(w http.ResponseWriter, r *http.Request) {
	// 从 Cookie 读取用户名
	var username string
	cookie, err := r.Cookie("username")
	if err == nil {
		username = cookie.Value
	}

	// 构造传给模板的数据
	data := struct {
		User     string
		Messages []Message
	}{
		User:     username,
		Messages: messages,
	}

	tmpl := template.Must(template.ParseFiles("templates/index.html"))
	tmpl.Execute(w, data)
}
步骤三:添加 /login 处理函数
go 复制代码
func login(w http.ResponseWriter, r *http.Request) {
	if r.Method != "POST" {
		http.Redirect(w, r, "/", http.StatusSeeOther)
		return
	}

	username := strings.TrimSpace(r.FormValue("username"))
	if username == "" || len(username) > 20 {
		http.Error(w, "昵称不能为空且不超过20字", http.StatusBadRequest)
		return
	}

	// 设置 Cookie,有效期 24 小时
	http.SetCookie(w, &http.Cookie{
		Name:   "username",
		Value:  username,
		MaxAge: 3600 * 24, // 秒
		Path:   "/",
	})

	http.Redirect(w, r, "/", http.StatusSeeOther)
}

并在 main() 里注册路由:

go 复制代码
http.HandleFunc("/login", login)
步骤四:发帖时也检查是否登录

修改 post 函数开头:

go 复制代码
// 检查是否登录
cookie, err := r.Cookie("username")
if err != nil {
	http.Redirect(w, r, "/", http.StatusSeeOther)
	return
}
// 后续可以用 cookie.Value 获取用户名(比如存进 Message)

✅ 现在流程是:

  1. 首次访问 → 输入昵称 → 设置 Cookie
  2. 刷新页面 → 自动识别你是谁
  3. 只有登录用户才能发帖!

✅ 4. 安全小贴士(第3章重点!)
  • 永远不要信任前端数据:即使前端写了"必填",后端也要校验。
  • Cookie 不是安全的:用户可以改 Cookie!所以不能存密码、权限等敏感信息。
  • 路径安全 :http.FileServer 要配合 StripPrefix,否则可能被遍历服务器文件!

✅ 5. 本章核心收获(一句话总结)
功能 Go 怎么做
提供 CSS/JS/图片 http.FileServer + http.Handle("/static/", ...)
表单校验 r.FormValue() + if 判断
记住用户 http.SetCookie() 和 r.Cookie()
模板传多个数据 用匿名 struct { User string; Messages []Message }

🔧 下一步挑战(可选)
  • 把用户名也显示在每条留言旁边(修改 Message 结构体,存 Username 字段)。
  • 添加"退出登录"按钮:设置 Cookie 的 MaxAge = -1 即可删除。
  • 用 securecookie 库对 Cookie 内容加密,防止用户伪造。

✅ 总结 :第3章让你的网站从"能用"变成"好用又安全"。

静态资源、表单处理、用户状态------这些都是真实项目天天打交道的东西。

现在你的 ChitChat 已经像个正经网站了!


相关推荐
别动我齐刘海2 小时前
C++ 工程化学习
java·linux·前端·c++·学习·机器学习·机器人
志尊宝3 小时前
Vue3 零基础每日笔记(071):暗黑模式与主题切换——CSS 变量 + Element Plus 暗黑方案
前端·css·笔记·vue·html·前端开发·软件开发
沪上企服通5 小时前
历史账套科目重映射与规则版本重算:旧账梳理的“口径复位”工程
笔记·架构
gjf05_056 小时前
人该怎样活着呢?版本75.8
学习
tachibana26 小时前
使用for range 的时候,它的地址会发生变化吗?
开发语言·后端·golang·go·语法
王中阳Go7 小时前
Go 后端转 AI:非科班怎么补?一张 3 列路线表(可保存)
开发语言·人工智能·后端·python·golang·大语言模型
li星野7 小时前
【学习记录】PCB与PCBA核心知识全解析:从设计到制造的关键细节
学习·制造
卿卿的产品经理日记8 小时前
【AI产品经理实战】Day 35|从“沉迷工具“到回归 AI 底层:Skill 收官、系统复盘与下一个 13 天
人工智能·学习·产品经理
一条泥憨鱼8 小时前
【从0开始学习计算机网络】| ARP 协议:地址解析,ARP 欺骗,链路层寻址
网络·后端·学习·计算机网络
HY小宝F9 小时前
树莓派智能摄像头系统 30 天重学计划之 Day 04 · HTTP / API:控制链入口 —— 学习总结
网络协议·学习·http