用net/http实现轻量博客系统:路由直连Handler,html/template渲染预编译Markdown,os.ReadDir按文件名排序列表,static目录托管静态资源,规避框架与数据库复杂度。

用 Go 写一个能跑起来的博客系统,核心不在框架选型,而在路由、模板和数据存取这三块怎么不绕弯子。
用 net/http 搭基础路由,别急着上 gin 或 echo
刚起步时引入第三方 Web 框架反而会模糊 HTTP 本质。直接用标准库,几行就能跑通首页、文章页、后台入口:
-
http.HandleFunc("/", homeHandler)处理首页,返回 Markdown 渲染后的文章列表 -
http.HandleFunc("/post/", postHandler)用 URL 路径后缀匹配文章 ID,比如/post/2024-05-10-my-first-post -
http.HandleFunc("/admin/", adminHandler)加个简单 BasicAuth 中间件(http.StripPrefix+http.HandlerFunc包一层)就足够临时管理
好处是:没有中间件生命周期干扰,http.ResponseWriter 和 *http.Request 的流向一目了然;坏处是路由不支持正则或参数自动提取——但初期几十篇博客根本不需要。
用 html/template 渲染页面,把 Markdown 当字符串塞进去
不用集成 blackfriday 或 goldmark 做实时解析。先把内容存在 .md 文件里,启动时一次性读取、转成 HTML 并缓存到内存 map:
立即学习“go语言免费学习笔记(深入)”;
- 文件结构按日期命名:
content/2024-05-10-hello.md,标题从首行 `# Hello` 提取,正文交给goldmark.Parse()+goldmark.Render() - 模板里用
{{.Content | safeHTML}}输出,避免被转义;safeHTML是自定义函数,注册进template.FuncMap - 别在模板里调用
os.ReadFile—— 每次请求都读磁盘,QPS 上不去还容易出错
这样省去数据库依赖,本地写完 .md 文件,go run main.go 就生效,适合内容更新频率低的个人博客。
dmSOBC SHOP网店系统由北京时代胜腾信息技术有限公司(http://www.webzhan.com)历时6个月开发完成,本着简单实用的理念,商城在功能上摒弃了外在装饰的一些辅助功能,尽可能的精简各项模块开发,做到有用的才开发,网店V1.0.0版本开发完成后得到了很多用户的使用并获得了好评,公司立即对网店进行升级,其中包括修正客户提出的一些意见和建议,现对广大用户提供免费试用版本,如您在使用
用 os.ReadDir 列目录代替数据库查询
文章列表页不需要 SQL ORDER BY created_at DESC。Go 1.16+ 的 os.ReadDir 返回按文件名排序的 fs.DirEntry 切片,而文件名设计为 YYYY-MM-DD-title.md,天然可排序:
-
entries, _ := os.ReadDir("content"),遍历过滤掉非.md文件 - 用
strings.TrimSuffix(entry.Name(), ".md")得到路径片段,再用strings.SplitN(..., "-", 3)提取日期和 slug - 注意:Windows 下文件系统可能不区分大小写,
.MD和.md会被视为同一文件,统一用小写扩展名更稳妥
这个方案在百篇以内文章时性能无压力,且规避了 SQLite 初始化、migration、连接池等额外复杂度。
静态资源走 http.FileServer,但别暴露源码目录
CSS、JS、图片放在 static/ 下,用 http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static/")))) 挂载即可。关键点在于:
- 不要把
content/或templates/目录挂成静态服务,否则用户访问/content/xxx.md就能直接下载源文件 - 如果用了
go:embed打包静态资源,记得在main.go顶部加//go:embed static/*,且http.FileServer要换成http.FS(assets),其中assets是embed.FS类型 - 开发时用
http.ServeFile单独 servefavicon.ico更灵活,避免因路径问题返回 404
真正卡住人的往往不是功能实现,而是某次部署后 CSS 不加载、或者 Markdown 图片路径拼错导致整页空白——这些全在静态资源路径和模板中 src 属性的硬编码里。









