Golang中使用Apache嵌入文件的实现方法

Golang中使用Apache嵌入文件的实现方法 大家好。

这是一个使用嵌入式文件系统存储CSS和JS文件的简单Web应用程序。

package main

import (
	"embed"
	"io/fs"
	"net/http"
)

//go:embed static/*
var StaticFiles embed.FS

type StaticPath struct {
	StaticP embed.FS
}

func (s StaticPath) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	publicFS, _ := fs.Sub(s.StaticP, "static")
	http.FileServer(http.FS(publicFS)).ServeHTTP(w, req)
}

func NewRouter() *http.ServeMux {
	r := http.NewServeMux()
	r.Handle("/", StaticPath{
		StaticP: StaticFiles,
	})
	return r
}

func main() {
	srv := &http.Server{
		Addr:    "localhost:3000",
		Handler: NewRouter(),
	}

	_ = srv.ListenAndServe()
}

目录结构:

  ├── go.mod
  ├── go.sum
  ├── main.go
  └── static
      ├── index.html
      └── style.css

2个目录,5个文件 Apache 2的配置如下:(cat /etc/apache2/conf-enabled/app1.conf)

<VirtualHost *:80>
    ProxyPass /app1 http://localhost:3000/
    ProxyPassReverse /app1 http://localhost:3000/
</VirtualHost>

HTML页面可以正常访问,但static文件夹中的CSS和JS文件无法访问。 我不知道问题出在哪里。有人能帮助我吗?


更多关于Golang中使用Apache嵌入文件的实现方法的实战教程也可以访问 https://www.itying.com/category-94-b0.html

2 回复

Gutsycat:

publicFS, _ := fs.Sub(s.StaticP, "static")

我对嵌入式文件或Apache一无所知,但我知道,检查错误而不是忽略它们通常会提供线索。

更多关于Golang中使用Apache嵌入文件的实现方法的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


问题在于你的路由配置。当前代码将根路径 / 映射到静态文件处理器,但Apache代理将请求转发到 /app1 路径。当浏览器请求CSS文件时,它访问的是 /app1/static/style.css,而你的Go应用只处理根路径 / 下的请求。

以下是修正后的代码:

package main

import (
	"embed"
	"io/fs"
	"net/http"
)

//go:embed static/*
var StaticFiles embed.FS

func NewRouter() *http.ServeMux {
	r := http.NewServeMux()
	
	// 创建子文件系统,剥离"static"前缀
	subFS, _ := fs.Sub(StaticFiles, "static")
	
	// 将静态文件服务挂载到根路径
	fileServer := http.FileServer(http.FS(subFS))
	r.Handle("/", fileServer)
	
	return r
}

func main() {
	srv := &http.Server{
		Addr:    "localhost:3000",
		Handler: NewRouter(),
	}

	_ = srv.ListenAndServe()
}

或者,如果你需要保持原有的StaticPath结构,可以这样修改:

package main

import (
	"embed"
	"io/fs"
	"net/http"
)

//go:embed static/*
var StaticFiles embed.FS

type StaticPath struct {
	StaticP embed.FS
}

func (s StaticPath) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	// 剥离URL路径中的"/app1"前缀(由Apache代理添加)
	req.URL.Path = req.URL.Path[len("/app1"):]
	
	publicFS, _ := fs.Sub(s.StaticP, "static")
	http.FileServer(http.FS(publicFS)).ServeHTTP(w, req)
}

func NewRouter() *http.ServeMux {
	r := http.NewServeMux()
	r.Handle("/app1/", StaticPath{
		StaticP: StaticFiles,
	})
	return r
}

func main() {
	srv := &http.Server{
		Addr:    "localhost:3000",
		Handler: NewRouter(),
	}

	_ = srv.ListenAndServe()
}

关键修改点:

  1. 路由处理器需要处理 /app1/ 路径(包含尾部斜杠)
  2. 在ServeHTTP方法中移除URL路径中的 /app1 前缀
  3. 使用 fs.Sub 正确剥离嵌入式文件系统中的 static 目录前缀

这样配置后,当Apache将 /app1/static/style.css 的请求转发到Go应用时,应用会正确地将路径映射到嵌入式文件系统中的 style.css 文件。

回到顶部