http.FileServer 只提供 index.html

Kyl*_*yle 0 http go mux

我的简单文件服务器代码:

package main

import (
    "net/http"
    "os"

    "github.com/gorilla/handlers"
    "github.com/gorilla/mux"
)

func main() {
    r := mux.NewRouter()

    // default file handler
    r.Handle("/", http.FileServer(http.Dir("web")))

    // run on port 8080
    if err := http.ListenAndServe(":8080", handlers.LoggingHandler(os.Stdout, r)); err != nil {
        panic(err)
    }
}
Run Code Online (Sandbox Code Playgroud)

我的目录结构是:

cmd/server/main.go
web/index.html
web/favicon.ico
web/favicon.png
web/css/main.css
Run Code Online (Sandbox Code Playgroud)

index.html要求main.css. 所以当我运行时,go run cmd/server/main.go我得到以下输出:

127.0.0.1 - - [24/Dec/2019:22:45:26 -0X00] "GET / HTTP/1.1" 304 0
127.0.0.1 - - [24/Dec/2019:22:45:26 -0X00] "GET /css/main.css HTTP/1.1" 404 19
Run Code Online (Sandbox Code Playgroud)

我可以看到index.html页面,但没有 CSS。当我请求任何其他文件(例如favicon.ico)时,我也会收到 404。为什么我的FileServeronly serve index.html

Bri*_*its 5

为了演示为什么这不起作用,请考虑以下测试应用程序:

package main

import (
    "fmt"
    "net/http"

    "github.com/gorilla/mux"
)

type testHandler struct{}

func (h *testHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    fmt.Printf("Got request for %s\n", r.URL)
}

func main() {
    r := mux.NewRouter()
    hndlr := testHandler{}
    r.Handle("/", &hndlr)

    // run on port 8080
    if err := http.ListenAndServe(":8080", r); err != nil {
        panic(err)
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您运行它并http://127.0.0.1:8080/在您的浏览器中访问它会记录Got request for /。但是,如果您访问, http://127.0.0.1:8080/foo您将收到 404 错误并且不会记录任何内容。这是因为r.Handle("/", &hndlr)只会匹配它/,而不匹配它下面的任何东西。

如果您将其更改为r.PathPrefix("/").Handler(&hndlr),它将按您的预期工作(路由器会将所有路径传递给处理程序)。因此,要将您的示例更改r.Handle("/", http.FileServer(http.Dir("web")))r.PathPrefix("/").Handler( http.FileServer(http.Dir("web"))).

注意:因为这是传递所有路径,FileServer所以真的没有必要使用 Gorilla Mux;我假设您将使用它来添加一些其他路线,因此我将其留在了这里。