跳到主要内容
Go Web 开发必备核心理论 | 极客日志
Go / Golang
Go Web 开发必备核心理论 Go Web 开发涉及 HTTP 协议状态码、请求方法、缓存机制及 HTTPS 原理。掌握 Cookie 与 Session 解决无状态问题,利用 sqlx 包操作 MySQL 实现增删改查。通过 template 引擎解耦视图与控制器,处理文件上传下载。理解 GET 与 POST 在语义、参数传递及幂等性上的区别,构建高效稳定的 Web 服务架构。
筑梦师 发布于 2026/4/8 更新于 2026/4/23 0 浏览HTTP 状态码
意义
每个状态码都是 HTTP 设计者对'网络通讯'中可能出现的情况的假设、预判。它相当于现实世界的信号灯,就像大家一遇到 404,就知道资源找不到了;一遇到 500 就知道服务器挂了。这种共识,也就是如今万维网的高效率的基础之一。
HTTP 状态码是日常开发、修改 Bug 的必备知识。常见状态码分类如下。
1、必须掌握的状态码
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:服务器内部错误。
2、需要理解的状态码
排查问题时常用。
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:服务器暂不可用,正在维修。
HTTP 协议
核心
1、HTTP 的本质
**定义:**超文本传输协议。
核心模型: 【请求 + 响应】客户端发送请求、服务器响应,一问一答的进行传递信息。
**无状态:**服务器不会记住上一次请求(后期引入了 Cookie、Session)。
**位置:**HTTP 协议存放在应用层,规范(客户端 - 服务器)的传输格式、交互流程。
2、URL 结构
例如:https://www.example.com:8080/path?name=test#fragment
https:使用的协议类型。
www.example.com:域名(对应服务器的 IP 地址)。
8080:端口号,HTTP 默认是 80,HTTPS 默认是 443,可省略。
/path:资源路径。
?name=test:访问资源时,用 GET 携带的参数。
#fragment:锚点。
3、请求方法(Method)
GET:只是请求资源,不会对服务器资源造成影响。
POST:提交数据,在服务器创建新的资源。
PUT:更新数据,若无资源,则新创建(与 POST 不同,是幂等的)。
DELETE:删除数据(一般会有 204)。
PATCH:修改部分资源(与 PUT 类似,但 PUT 是更新整个资源)。
4、状态码分类
1xx:信息性状态码。
2xx:请求成功。
3xx:重定向。
4xx:客户端错误。
5xx:服务器错误。
进阶必备知识
1、HTTP 版本演进
HTTP/1.0:每次访问,都会重新建立一个连接。
HTTP/1.1:在 1.0 的基础上,建立了持久化连接,但是只能串行的发送请求。
HTTP/2:可以多路复用(一个连接同时发多个请求,互不阻塞)。
HTTP/3:引入了 UDP,解决了 TCP 头部堵塞问题(标:彻底抛弃了 TCP 协议,转而应用了 UDP)。
2、缓存机制
强缓存:服务器通过 Cache-Control: max-age=3600 告诉浏览器,1h 内,访问该地址,强制访问本地缓存(怪不得我更改了服务器的资源后,客户端依旧不变),除非(Ctrl+F5 强制刷新)。
协商缓存:如果强缓存过期,浏览器发请求时带 If-Modified-Since 或 Etag,服务器判断资源没改就返回 304,让浏览器继续用缓存。
3、HTTPS 原理
**核心区别:**HTTP 是明文传输,HTTPS 是 HTTP+TLS 组合,数据会加密。
**SSL/TLS 的作用:**像"加密信封",让 HTTP 数据更安全:
加密 :把明文数据(如密码、订单信息)变成密文,即使被截获也无法破解。
身份认证 :验证服务器的身份,防止是钓鱼网站。
完整性校验 :确保信息没有被篡改。
4、Cookie 和 Session
Cookie:服务器通过 set-cookie,在客户端存一些信息,解决 HTTP 协议无状态问题。
Session:服务端存储的用户信息,与 Cookie 中的 sessionid 关联。(登入时服务器,通过向 Cookie 中,设置 sessionid。下次可以通过 sessionid 在 Session 中找到相应信息)。
5、跨域资源共享(CORS)
跨域:来自同源策略(协议、域名、端口有个不同,就不属于同一域)。
解决:服务器返回 Access-Control-Allow-Origin 响应头,允许指定域名的跨域请求。
MySQL 的连接与增删改查 本篇是通过 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"
Cookie
起源 Cookie 的名字可不是随便起的,它源于 Unix 中的 "magic cookie",魔幻小饼干 --- 程序之间用于传递特定信息或状态的小数据包。
被网景公司的天才程序员,于 1994 年,在解决不让'电商'服务器承担更多消息时,灵光一现想出来的东西。
后来也因为悄悄记录了用户信息,因 Cookie'隐蔽跟踪'的本质,而引起了一时的大众恐慌。
应用
后端的核心操作 func serv (w http.ResponseWriter, r *http.Request) {
cookie := &http.Cookie{
Name: "session_id" ,
Value: "cookie" ,
Expires: time.Now().Add(time.Second),
}
http.SetCookie(w, cookie)
c, _ := r.Cookie("session_id" )
_, err := fmt.Fprintln(w, c.Name, c.Value, c.Expires)
if err != nil {
fmt.Println("..." )
}
cs := r.Cookies()
for n, co := range cs {
_, err = fmt.Fprintln(w, n, co.Name)
}
}
Template 模板起源于远古时代(最早至 3 万年前),为批量生产特定的物品而生。
与二十世纪八九十年代,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 )
}
上传 <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 核心区别 一般需要着重注意 GET 与 POST 的本质区别(从语义、参数传递、幂等性、缓存等角度)。
**语义:**GET 是获取资源,POST 是提交资源。
**参数:**GET 是参数在 URL,POST 在请求体。
**幂等性:**GET 多次执行结果不变(幂等),POST 可能多次提交(非幂等、多次下单)。
**缓存:**GET 易被缓存,POST 一般不缓存。
相关免费在线工具 Base64 字符串编码/解码 将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
Base64 文件转换器 将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
Markdown转HTML 将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online
HTML转Markdown 将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online
JSON 压缩 通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online
JSON美化和格式化 将JSON字符串修饰为友好的可读格式。 在线工具,JSON美化和格式化在线工具,online