第二个文件服务器提供 html 但不提供图像

Second FileServer serves html but not images

我 运行 在构建一个简单的 API 时遇到了 Go 和 gorilla/mux 路由器的以下问题。我敢肯定这是我脸上常见的愚蠢错误,但我看不到它。

简化的项目结构

|--main.go
|
|--public/--index.html
|        |--image.png
|
|--img/--img1.jpg
|     |--img2.jpg
|     |--...
|...

main.go

package main

import (
    "net/http"
    "github.com/gorilla/mux"
)

var Router = mux.NewRouter()

func InitRouter() {
    customers := Router.PathPrefix("/customers").Subrouter()

    customers.HandleFunc("/all", getAllCustomers).Methods("GET")
    customers.HandleFunc("/{customerId}", getCustomer).Methods("GET")
    // ...
    // Registering whatever middleware
    customers.Use(middlewareFunc)

    users := Router.PathPrefix("/users").Subrouter()

    users.HandleFunc("/register", registerUser).Methods("POST")
    users.HandleFunc("/login", loginUser).Methods("POST")
    // ...

    // Static files (customer pictures)
    var dir string
    flag.StringVar(&dir, "images", "./img/", "Directory to serve the images")
    Router.PathPrefix("/static/").Handler(http.StripPrefix("/static/", http.FileServer(http.Dir(dir))))

    var publicDir string
    flag.StringVar(&publicDir, "public", "./public/", "Directory to serve the homepage")
    Router.Handle("/", http.StripPrefix("/", http.FileServer(http.Dir(publicDir))))
}

func main() {
    InitRouter()
    // Other omitted configuration
    server := &http.Server{
        Handler: Router,
        Addr:    ":" + port,
        // Adding timeouts
        WriteTimeout: 15 * time.Second,
        ReadTimeout:  15 * time.Second,
    }

    err := server.ListenAndServe()
    // ...
}

子路由工作正常,中间件和所有。如果我转到 localhost:5000/static/img1.png.

img 下的图像会正确投放

问题是,去 localhost:5000 服务于 public 中的 index.html,但是 localhost:5000/image.png404 not found

这里发生了什么?

更改此行:

// handles '/' and *ONLY* '/'
Router.Handle("/",
        http.StripPrefix("/", http.FileServer(http.Dir(publicDir))))

为此:

// handles '/' and all sub-routes
Router.PathPrefix("/").Handler(
        http.StripPrefix("/",http.FileServer(http.Dir(publicPath))))

基本上,在您的原始代码中,/ 的路由器正在处理这条路径并且只处理那条路径(没有子路径)。

您可能想知道为什么您的原始代码 "worked" 至少用于一个文件 (index.html)。原因是 http.FileServer 给定的路径是目录 - 而不是文件 - 将默认提供索引页面文件 index.html(请参阅 FileServer source)。

使用 PathPrefix 允许(文件服务器)处理程序接受路径 /.

下的 所有 URL 路径