如何为Go默认HTTP文件服务器添加自定义HTML页眉页脚?
解决Go HTTP文件服务器添加自定义页眉页脚的方案
要在不复制修改dirList函数的前提下,给默认目录列表添加自定义页眉和页脚,可以通过响应捕获中间件实现:拦截目录列表的HTML输出,在前后拼接自定义内容后再返回给客户端。
完整实现代码
package main import ( "bytes" "log" "net/http" "strconv" ) // responseCapturer 用于捕获HTTP响应内容 type responseCapturer struct { http.ResponseWriter buffer bytes.Buffer status int } func (rc *responseCapturer) WriteHeader(code int) { rc.status = code // 暂不向客户端写入状态码,等处理完内容后统一输出 } func (rc *responseCapturer) Write(b []byte) (int, error) { return rc.buffer.Write(b) } // addHeaderFooter 中间件:为目录列表HTML添加自定义页眉页脚 func addHeaderFooter(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // 先判断当前请求路径是否为目录 fs := http.Dir(".") // 这里替换为你实际使用的文件系统根目录 file, err := fs.Open(r.URL.Path) if err != nil { next.ServeHTTP(w, r) return } defer file.Close() fi, err := file.Stat() if err != nil || !fi.IsDir() { // 非目录请求,直接转发给原处理器 next.ServeHTTP(w, r) return } // 是目录请求,捕获原响应内容 rc := &responseCapturer{ResponseWriter: w, status: http.StatusOK} next.ServeHTTP(rc, r) // 仅处理dirList生成的HTML响应 if rc.status == http.StatusOK && w.Header().Get("Content-Type") == "text/html; charset=utf-8" { // 自定义页眉和页脚 customHeader := `<html><head><title>My files</title></head><body>` customFooter := `<p>And that's all, folks!</p></body></html>` // 拼接完整HTML内容 fullContent := customHeader + rc.buffer.String() + customFooter // 更新响应头的Content-Length w.Header().Set("Content-Length", strconv.Itoa(len(fullContent))) // 输出最终内容 w.WriteHeader(rc.status) w.Write([]byte(fullContent)) } else { // 非预期响应,直接输出捕获的内容 w.WriteHeader(rc.status) w.Write(rc.buffer.Bytes()) } }) } func main() { // 创建默认文件服务器 fileServer := http.FileServer(http.Dir(".")) // 应用中间件 http.Handle("/", addHeaderFooter(fileServer)) log.Println("Server starting on :8090...") log.Fatal(http.ListenAndServe(":8090", nil)) }
关键说明
- 响应捕获器:
responseCapturer实现了http.ResponseWriter接口,把原响应内容暂存到缓冲区,而不是直接发送给客户端。 - 目录判断:先检查请求路径是否为目录,避免对文件下载等非目录请求进行处理。
- 内容拼接:仅针对
dirList生成的text/html类型响应,将自定义页眉、原目录列表内容、页脚拼接后返回,同时更新Content-Length确保响应正确。 - 无侵入性:完全不需要修改
fs.go中的dirList函数,保留了原目录列表的所有逻辑。
内容的提问来源于stack exchange,提问作者ubndpdhsc
相关产品推荐
相关产品推荐

