每次写完前端页面想本地预览,用 Python 的 python -m http.server 总觉得不够灵活——没法自定义端口、不想让别人看到目录列表、还想加点简单的日志。今天用 OpenCode 写一个 Go 语言的命令行静态文件服务器,一行命令启动,支持自定义端口、目录浏览开关和访问日志。
net/http./fileserver -port 3000 -dir ./public 即可启动npm i -g @anthropic-ai/opencode 或参考 opencode.ai)我对 OpenCode 说:
> 帮我在当前目录初始化一个 Go 项目,模块名是 fileserver,写一个 main.go,功能是启动一个 HTTP 静态文件服务器,监听 8080 端口,从当前目录提供文件服务。
OpenCode 生成了 go mod init fileserver 和基础代码:
package main
import (
"log"
"net/http"
)
func main() {
port := ":8080"
dir := "."
http.Handle("/", http.FileServer(http.Dir(dir)))
log.Printf("文件服务器已启动,监听 %s,服务目录 %s", port, dir)
if err := http.ListenAndServe(port, nil); err != nil {
log.Fatal(err)
}
}
要点:Go 标准库的 http.FileServer 已经提供了静态文件服务能力,三行核心代码就搞定了。但默认的 http.Dir 会暴露目录列表,后续需要处理。
我对 OpenCode 说:
> 把端口和目录改成命令行参数,用 flag 包,同时增加一个 -browse 参数控制是否显示目录列表。再加个 -host 参数。
OpenCode 理解了需求,改写了 main 函数:
package main
import (
"flag"
"log"
"net/http"
)
func main() {
port := flag.String("port", "8080", "监听端口")
host := flag.String("host", "0.0.0.0", "绑定地址")
dir := flag.String("dir", ".", "静态文件目录")
browse := flag.Bool("browse", false, "是否启用目录浏览")
flag.Parse()
addr := *host + ":" + *port
log.Printf("文件服务器已启动,监听 %s,服务目录 %s", addr, *dir)
log.Fatal(http.ListenAndServe(addr, handler(*dir, *browse)))
}
要点:Go 的 flag 包是标准库的一部分,不需要外部依赖。解析后的值是指针,用 * 解引用。
我对 OpenCode 说:
> 把 handler 实现出来。如果 browse 为 false,用自定义的文件系统包装一层,返回 404 而不是目录列表。同时给每个请求加上访问日志。
OpenCode 生成了完整的 handler 实现,大概 40 行代码。核心思路是:包装 http.FileSystem,在 Open 方法中判断路径是不是目录,如果是且不允许浏览,就返回一个"不存在的文件"错误,这样 http.FileServer 会自动返回 404。
func handler(dir string, browse bool) http.Handler {
fs := http.FileServer(noDirList{http.Dir(dir), browse})
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
log.Printf("%s %s %s", r.RemoteAddr, r.Method, r.URL.Path)
fs.ServeHTTP(w, r)
})
}
我对 OpenCode 说:
> 帮我启动这个服务器,然后用 curl 测试一下,验证根路径能不能访问,目录浏览关闭时是不是返回 404。
OpenCode 启动了服务器后台进程,然后执行了测试命令。输出显示:
GET / 返回了 index.html(200 OK)GET /subdir/(无 index.html 的子目录)返回 404 —— 目录浏览已关闭-browse true 时目录列表正常显示要点:OpenCode 不仅能写代码,还能帮你运行和测试,省去了手动验证的环节。
package main
import (
"flag"
"log"
"net/http"
"os"
)
type noDirList struct {
fs http.FileSystem
browse bool
}
func (n noDirList) Open(path string) (http.File, error) {
f, err := n.fs.Open(path)
if err != nil {
return nil, err
}
if n.browse {
return f, nil
}
stat, err := f.Stat()
if err != nil {
f.Close()
return nil, err
}
if stat.IsDir() {
f.Close()
return nil, os.ErrNotExist
}
return f, nil
}
func handler(dir string, browse bool) http.Handler {
fs := http.FileServer(noDirList{http.Dir(dir), browse})
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
log.Printf("%s %s %s", r.RemoteAddr, r.Method, r.URL.Path)
fs.ServeHTTP(w, r)
})
}
func main() {
port := flag.String("port", "8080", "监听端口")
host := flag.String("host", "0.0.0.0", "绑定地址")
dir := flag.String("dir", ".", "静态文件目录")
browse := flag.Bool("browse", false, "是否启用目录浏览")
flag.Parse()
addr := *host + ":" + *port
log.Printf("文件服务器已启动 → http://%s", addr)
log.Printf("服务目录: %s | 目录浏览: %v", *dir, *browse)
if err := http.ListenAndServe(addr, handler(*dir, *browse)); err != nil {
log.Fatal(err)
}
}
这个小项目从想法到可运行,在 OpenCode 的帮助下不到 5 分钟就完成了。实际的编码工作——写 noDirList 包装结构、Open 方法的错误处理逻辑、命令行参数解析——这些原本需要查文档、试错的过程,现在直接用自然语言描述需求,OpenCode 就能生成符合预期的代码。
相比传统开发方式,时间主要节省在:
不需要查文档:Go 标准库的接口签名、http.FileSystem 的定义,OpenCode 全都知道
即时测试验证:写完代码当场运行、当场调试
关注点分离:你把精力放在"想做什么",而不是"怎么写"
如果你还没试过用 AI 编程助手做日常开发,从这个 100 行的小工具开始,是个不错的切入点。