Go http/server自定义路由下根路径已注册路由时如何提供静态文件服务
实现静态文件服务的修改方案
你当前的路由逻辑为正则精确匹配(所有路由规则都加了^和$锚定),所以已注册的/端点只会匹配根路径请求,不会拦截其他子路径请求,只需要在现有路由逻辑的基础上补充静态文件处理逻辑即可,可保证优先匹配已注册的业务路由,未匹配到的请求自动尝试从static目录读取静态文件。
方案1:修改Serve函数兜底逻辑(推荐)
该方案不需要修改现有路由注册规则,侵入性最小:
- 新增全局静态文件处理器
// 初始化静态文件处理器,将static目录映射到网站根路径 var staticHandler = http.StripPrefix("/", http.FileServer(http.Dir("static")))
- 修改Serve函数末尾逻辑,将原直接返回404的逻辑替换为静态文件处理
func Serve(w http.ResponseWriter, r *http.Request) { var allow []string for _, route := range routes { matches := route.regex.FindStringSubmatch(r.URL.Path) if len(matches) > 0 { if r.Method != route.method { allow = append(allow, route.method) continue } ctx := context.WithValue(r.Context(), ctxKey{}, matches[1:]) route.handler(w, r.WithContext(ctx)) return } } if len(allow) > 0 { w.Header().Set("Allow", strings.Join(allow, ", ")) http.Error(w, "405 method not allowed", http.StatusMethodNotAllowed) return } // 替换原有的http.NotFound(w, r),走静态文件处理逻辑 staticHandler.ServeHTTP(w, r) }
方案2:注册通配静态路由
如果希望把静态文件处理也纳入routes列表统一管理,可以新增一条通配路由,必须放在所有路由的最后面,确保优先级低于业务路由:
var routes = []route{ newRoute("GET", "/", home), // 其他所有业务路由都放在静态路由前面 newRoute("GET", `/(.*)`, func(w http.ResponseWriter, r *http.Request) { http.StripPrefix("/", http.FileServer(http.Dir("static"))).ServeHTTP(w, r) }), }
两种方案都可以保证原有的/端点路由正常工作,访问根路径时返回home handler的响应,访问/test.jpg、/css/style.css等路径时,会自动读取static目录下的对应文件返回。
内容的提问来源于stack exchange,提问作者Bodito
相关产品推荐
相关产品推荐

