HTTP 状态码
状态码意义
每个状态码都是 HTTP 设计者对网络通讯中出现情况的假设与预判。它相当于现实世界的信号灯,例如遇到 404 就知道资源找不到,遇到 500 就知道服务器挂了。这种共识是万维网高效率的基础之一。
HTTP 状态码是日常开发、修改 Bug 的必备工具。常见状态码分类如下:
Go Web 开发的基础知识,涵盖 HTTP 状态码分类与含义、HTTP 协议核心概念(版本演进、缓存、HTTPS、Cookie/Session)、MySQL 数据库操作(使用 sqlx 包)、模板引擎、文件上传下载以及控制器模式。重点讲解了 GET 与 POST 方法的区别及常见应用场景,适合初学者构建 Go Web 应用基础。

每个状态码都是 HTTP 设计者对网络通讯中出现情况的假设与预判。它相当于现实世界的信号灯,例如遇到 404 就知道资源找不到,遇到 500 就知道服务器挂了。这种共识是万维网高效率的基础之一。
HTTP 状态码是日常开发、修改 Bug 的必备工具。常见状态码分类如下:
200 OK:最常见的状态码,代表请求完全正确,如打开网页、调用 API。
301 Moved Permanently:资源永久迁移(例如访问 a.com 会被重定向到 b.com)。
302 Found:部分资源临时迁移。
400 Bad Request:请求出错,参数缺失等。
401 Unauthorized:未登录。
403 Forbidden:已登录,但无权限。
404 Not Found:资源不存在。
500 Internal Server Error:服务器内部错误。
排查问题时常用:
100 Continue
201 Created:资源创建成功(POST)。
204 No Content:处理成功,但不返回资源(DELETE)。
206 Partial Content:处理成功了一部分。
304 Not Modified:资源未修改,可直接使用缓存。
405 Method Not Allowed:方法不被允许。
408 Request Timeout:请求超时。
502 Bad Gateway:作为网关/代理时,收到无效响应。
503 Service Unavailable:服务器暂不可用,正在维护。
HTTPS = HTTP + TLS
本篇是通过 sqlx 包进行操作的,对数据库/sql 操作进行了通用拓展。
import (
_ "github.com/go-sql-driver/mysql"
"github.com/jmoiron/sqlx"
)
// 核心的两步
DB, err := sqlx.Open("mysql", "root:1234@tcp(localhost:3306)/goweb?parseTime=true&loc=Local")
DB.Ping()
// 语句
queryCreate := "insert into user (id,name) values (?,?)"
queryDelete := "delete from user where id =?"
queryUpdate := "update user set name=? where id=?"
queryQuery := "select * from user"
// 执行
// 增:DB.Exec(query, 1, "白小纯")
// 删:DB.Exec(query, 1)
// 改:DB.Exec(query, "夜藏", 1)
// 查:rows, err := DB.Query(query)
// for rows.Next() {
// rows.Scan(&id, &name)
// }
Cookie 的名字源于 Unix 中的 "magic cookie",即程序之间用于传递特定信息或状态的小数据包。
被网景公司的程序员于 1994 年提出,最初是为了解决不让电商服务器承担更多消息时灵光一现想出来的东西。
后来也因为悄悄记录了用户信息,因 Cookie'隐蔽跟踪'的本质,而引起过大众恐慌。
func serv(w http.ResponseWriter, r *http.Request) {
// cookie 赋值
cookie := &http.Cookie{
Name: "session_id",
Value: "cookie",
Expires: time.Now().Add(time.Second),
}
http.SetCookie(w, cookie)
// 获取单个 cookie
c, _ := r.Cookie("session_id")
_, err := fmt.Fprintln(w, c.Name, c.Value, c.Expires)
if err != nil {
fmt.Println("...")
}
// 循环获取 cookie
cs := r.Cookies()
for n, co := range cs {
_, err = fmt.Fprintln(w, n, co.Name)
}
}
模板起源于远古时代,为批量生产特定的物品而生。
与二十世纪八九十年代,C++ 因泛型需求引入了模板。
后来 Web 方面为了解耦也引入了模板。
真正推动模板的是 MVC 架构的兴起——为了让控制器 (Control) 与视图 (View) 彻底分离,模板引擎起了关键作用。
模板简单来说就是预制结构的文本,其中包含占位符与控制逻辑,通过模板引擎的动态填充之后生产,最终输出。
// 后端界面
func temp(w http.ResponseWriter, r *http.Request) {
add := template.FuncMap{"add": Add}
t := template.New("index").Funcs(add)
t, _ = t.ParseFiles("new_add")
t.Execute(w, nil)
}
<!-- 前端 -->
{{add 0 0}}
从浏览器向服务器传输数据。
<form action="upload" enctype="multipart/form-data" method="post">
上传照片:<input type="file" name="photo">
</form>
func upload(w http.ResponseWriter, r *http.Request) {
f, _, _ := r.FormFile("photo")
b, _ := io.ReadAll(f)
err := ioutil.WriteFile("/..", b, 0777)
if err != nil {
fmt.Println("失败")
}
}
<a href="download?filename=file.png">点击我下载</a>
func download(w http.ResponseWriter, r *http.Request) {
name := r.FormValue("filename")
ReadFile, _ := os.ReadFile("地址" + name)
h := w.Header()
h.Set("Content-Type", "application/octet-stream")
h.Set("Content-Disposition", "attachment; filename=photo")
fmt.Fprintln(w, ReadFile)
}
type myStruct struct{}
func (m myStruct) ServeHTTP(w http.ResponseWriter, r *http.Request) {}
func main() {
s := http.Server{
Addr: "localhost:8888",
Handler: myStruct{},
}
}
func Test(w http.ResponseWriter, r *http.Request) {}
func main() {
server := http.Server{
Addr: "localhost:8888",
}
http.HandleFunc("url", Test)
server.ListenAndServe()
}
一般需要着重注意 GET 与 POST 的本质区别(从语义、参数传递、幂等性、缓存等角度)。

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML 转 Markdown 互为补充。 在线工具,Markdown 转 HTML在线工具,online
将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML 转 Markdown在线工具,online
通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online
将JSON字符串修饰为友好的可读格式。 在线工具,JSON美化和格式化在线工具,online