CORS 与 panic 恢复中间件
跨源策略与从 panic 中恢复
CORS 与 panic 恢复中间件 是 CoddyKit 上的免费 Go Academy 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Go Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Go Academy 课程共包含 4 节课。
什么是 CORS
跨源资源共享(CORS)是一种浏览器安全机制,用于限制哪些源可以向您的 API 发出 HTTP 请求。服务器通过设置响应标头选择启用该机制。
CORS 预检
在带有自定义标头或非简单方法的跨源请求之前,浏览器会发送 OPTIONS 预检请求。您的中间件必须处理 OPTIONS,并返回包含 CORS 标头的 200 响应。
CORS 中间件
用于开发环境的简单 CORS 中间件:
func CORS(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Access-Control-Allow-Origin", "https://myapp.com")
w.Header().Set("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE,OPTIONS")
w.Header().Set("Access-Control-Allow-Headers", "Authorization,Content-Type")
if r.Method == http.MethodOptions {
w.WriteHeader(http.StatusOK); return
}
next.ServeHTTP(w, r)
})
}允许的源
涉及凭据(Cookie、Authorization 标头)时,不要使用 Access-Control-Allow-Origin: *,而应使用明确的源。对于多个源,请与白名单进行匹配。
allowedOrigins := map[string]bool{
"https://app.example.com": true,
"https://dev.example.com": true,
}
if allowedOrigins[r.Header.Get("Origin")] {
w.Header().Set("Access-Control-Allow-Origin", r.Header.Get("Origin"))
}Access-Control-Allow-Credentials
允许跨源发送 Cookie 和授权标头:
w.Header().Set("Access-Control-Allow-Credentials", "true")rs/cors 库
在生产环境中,请使用 github.com/rs/cors 库,以获得功能完善的 CORS 支持,包括灵活的源匹配、凭据支持和预检缓存。
c := cors.New(cors.Options{
AllowedOrigins: []string{"https://example.com"},
AllowedMethods: []string{"GET","POST","PUT","DELETE"},
AllowedHeaders: []string{"Authorization","Content-Type"},
AllowCredentials: true,
})
handler := c.Handler(mux)恐慌恢复中间件
从恐慌中恢复,防止服务器崩溃并丢失所有活动连接:
func Recovery(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
defer func() {
if rec := recover(); rec != nil {
log.Printf("panic: %v\n%s", rec, debug.Stack())
http.Error(w, "Internal Server Error", 500)
}
}()
next.ServeHTTP(w, r)
})
}runtime/debug.Stack
发生恐慌时打印完整的 goroutine 堆栈跟踪,以帮助诊断根本原因:
import "runtime/debug"
log.Printf("panic: %v\n%s", rec, debug.Stack())Sentry 集成
在恢复中间件中,将恐慌发送到 Sentry 或类似的错误跟踪服务,然后再向客户端返回 500。
顺序:Recovery 位于最外层
请始终将 Recovery 注册为最外层(最先应用的)中间件,以便它捕获其他所有中间件和处理程序产生的恐慌。
handler := Recovery(RequestID(Logger(Auth(mux))))测试恐慌恢复
编写一个会故意引发恐慌的处理程序,通过 httptest 经由中间件调用它,并断言响应为 500。
panicHandler := http.HandlerFunc(func(_ http.ResponseWriter, _ *http.Request) { panic("test") })
w := httptest.NewRecorder()
Recovery(panicHandler).ServeHTTP(w, httptest.NewRequest("GET", "/", nil))
assert.Equal(t, 500, w.Code)快速检查
为什么恐慌恢复中间件必须位于最外层?
回顾:CORS 与恐慌恢复
要点:
- CORS:设置 Access-Control-Allow-* 标头;处理 OPTIONS 预检请求
- 涉及凭据时,Allow-Origin 使用明确的源,而不是 *
- 恢复:defer recover() + 记录堆栈跟踪 + 返回 500
- Recovery 必须是最外层的中间件
常见问题解答
「CORS 与 panic 恢复中间件」课时是免费的吗?
是的 — 「CORS 与 panic 恢复中间件」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Go Academy 课程的其余内容,请升级到 CoddyKit PRO。 Go Academy 课程共包含 4 节课。
「CORS 与 panic 恢复中间件」这节课中我会学到什么?
跨源策略与从 panic 中恢复 你通过在浏览器中直接运行的动手代码来练习 Go Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Go Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Go Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。
「CORS 与 panic 恢复中间件」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Go Academy 课中编写并运行代码吗?
能。每节 Go Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- HTTP 中间件链基础
- 日志记录与请求 ID 中间件
- 身份验证与速率限制中间件
- CORS 与 panic 恢复中间件