学习总结笔记三:让网站“活”起来——处理静态文件、表单验证与用户登录(第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.gomain() 函数里,加这一行:

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 小时前
深度学习笔记(b站2025李宏毅课程)
人工智能·笔记·深度学习
polarislove02142 小时前
9.3 输出比较-嵌入式铁头山羊STM32笔记
笔记·stm32·嵌入式硬件
硬件yun2 小时前
Flyback反激电路学习参数计算
学习
mudtools2 小时前
如何设计易维护、低学习成本的飞书.NET SDK组件
学习·.net·飞书
怪我冷i2 小时前
GORM 的 Migration API
数据库·postgresql·golang·ai编程·ai写作
弘毅 失败的 mian3 小时前
Git 标签管理
经验分享·笔记·git
崇山峻岭之间3 小时前
Matlab学习记录19
学习·算法·matlab
.鸣3 小时前
CSDN Java反射
java·学习
2501_946213903 小时前
Zettlr(科研笔记) v4.0.0 中文免费版
java·经验分享·笔记·pdf·github·ocr·开源软件