
本文介绍一种轻量、可嵌入的 Go 方案,通过 HTTP Host 头匹配 + 反向代理,实现在单进程内支持 mylocal.app、doc.mylocal.app、editor.mylocal.app 等本地子域名访问,完全避免修改 /etc/hosts 或系统 DNS,且不依赖外部工具。
本文介绍一种轻量、可嵌入的 Go 方案,通过 HTTP Host 头匹配 + 反向代理,实现在单进程内支持 `mylocal.app`、`doc.mylocal.app`、`editor.mylocal.app` 等本地子域名访问,完全避免修改 `/etc/hosts` 或系统 DNS,且不依赖外部工具。
要让本地应用支持 *.mylocal.app 这类子域名,核心难点在于:*浏览器发起请求时,DNS 解析必须将所有 `.mylocal.app指向127.0.0.1,但标准 Go 的http.ServeMux不支持基于Host头的路由匹配(仅支持路径前缀)**。幸运的是,我们无需实现 DNS 服务器或修改系统配置——只需一个“智能入口网关”,结合 Go 标准库的httputil.NewSingleHostReverseProxy`,即可在单个 HTTP 服务中完成子域名分发与透明代理。
以下是一个完整、简洁(约 30 行核心逻辑)、零外部依赖的实现:
免费 DNS 与邮件安全分析(IntoDNS.ai):包括 DNSSEC、SPF、DKIM、DMARC、MTA-STS、BIMI、SMTP STARTTLS、FCrDNS、黑名单、发件人要求及报告。
package main
import (
"fmt"
"log"
"net/http"
"net/http/httputil"
"net/url"
"strings"
)
func main() {
mux := http.NewServeMux()
// 主站:mylocal.app → ./ (根目录)
mux.Handle("/", hostRouter(map[string]http.Handler{
"mylocal.app": http.FileServer(http.Dir("./")),
"doc.mylocal.app": newProxy("./doc"),
"editor.mylocal.app": newProxy("./editor"),
}))
log.Println("Serving on :8080 — visit http://mylocal.app, http://doc.mylocal.app, etc.")
log.Fatal(http.ListenAndServe(":8080", mux))
}
// hostRouter 根据 Host 头选择 handler(支持精确匹配)
func hostRouter(handlers map[string]http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
host := strings.Trim(r.Host, ":8080") // 去除端口(如 localhost:8080 → localhost)
if h, ok := handlers[host]; ok {
h.ServeHTTP(w, r)
return
}
// 默认 fallback:返回 404 或重定向到主站(可选)
http.Error(w, fmt.Sprintf("Unknown host: %s", r.Host), http.StatusNotFound)
})
}
// newProxy 创建指向本地子目录的反向代理(自动处理静态资源路径)
func newProxy(dir string) http.Handler {
localURL, _ := url.Parse("http://127.0.0.1:0") // 占位符,实际由 director 替换
proxy := httputil.NewSingleHostReverseProxy(localURL)
proxy.Director = func(r *http.Request) {
r.URL.Scheme = "http"
r.URL.Host = "127.0.0.1:8080" // 本进程内复用同一端口
r.URL.Path = "/" + strings.TrimPrefix(r.URL.Path, "/") // 保持原始路径
// 注入 X-Forwarded-* 头(可选,便于后端识别)
r.Header.Set("X-Forwarded-Host", r.Host)
r.Header.Set("X-Forwarded-Proto", "http")
}
return proxy
}? 关键说明:
- ✅ 零系统修改:用户只需将浏览器代理设为
http://127.0.0.1:8080(Chrome 支持--proxy-server=127.0.0.1:8080启动参数),所有*.mylocal.app请求即被本程序捕获并按 Host 分发; - ✅ 真正的子域名语义:
doc.mylocal.app/css/main.css会被精准路由到./doc/css/main.css,无需路径重写; - ✅ 兼容 Hugo/mxGraph 等第三方静态站点:
newProxy使用反向代理而非FileServer,完美支持 Hugo 生成的相对路径、mxGraph 的index.html路由等; - ⚠️ 注意浏览器代理设置:此方案本质是「HTTP 显式代理」,需在浏览器中手动启用(非系统级),因此完全隔离、安全、可撤销;
- ? 若需 HTTPS 支持:可扩展为 MITM 代理(需生成本地 CA 并导入浏览器),但对纯本地开发,HTTP + 代理已足够高效可靠。
该方案平衡了简洁性、可维护性与功能性——它没有重复造轮子(复用 net/http 和 net/http/httputil),也没有引入重量级依赖,同时彻底规避了 /etc/hosts 维护难题和 DNS 服务复杂度,真正实现了“开箱即用”的本地子域名体验。

















