一尘不染

从根目录提供主页和静态内容

go

在Golang中,我如何在根目录之外提供静态内容,同时仍具有用于提供主页的根目录处理程序。

使用以下简单的Web服务器作为示例:

package main

import (
    "fmt"
    "net/http"
)

func main() {
    http.HandleFunc("/", HomeHandler) // homepage
    http.ListenAndServe(":8080", nil)
}

func HomeHandler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "HomeHandler")
}

如果我做

http.Handle("/", http.FileServer(http.Dir("./")))

我收到一个恐慌,说我有两个针对“
/”的注册。我在互联网上找到的每个Golang示例都建议从不同目录中提供其静态内容,但这对于sitemap.xml,favicon.ico,robots.txt和其他按惯例或始终必须从根本上得到服务。

我要寻找的行为是在大多数Web服务器(例如Apache,Nginx或IIS)中发现的行为,它首先遍历您的规则,如果没有找到规则,它将查找实际文件,如果没有找到文件,
404 我的猜测是,不是编写a http.HandlerFunc,而是需要编写a
http.Handler,它检查是否引用了具有扩展名的文件,如果是,则检查文件是否存在并提供文件,否则它是404s或提供主页,这是因为“
/”。不幸的是,我不确定如何开始这样的任务。

我的一部分说我正在使情况变得过于复杂,这使我觉得我缺少了什么?任何指导将不胜感激。


阅读 241

收藏
2020-07-02

共1个答案

一尘不染

我想到的一件事可能对您有所帮助,您可以创建自己的ServeMux。我在您的示例中添加了内容,使chttp是一个ServeMux,您可以为其提供静态文件。然后,HomeHandler会检查它是否应该提供文件。我只是检查一个“。”
但您可以做很多事情。只是一个想法,可能不是您想要的。

package main

import (
    "fmt"
    "net/http"
    "strings"
)

var chttp = http.NewServeMux()

func main() {

    chttp.Handle("/", http.FileServer(http.Dir("./")))

    http.HandleFunc("/", HomeHandler) // homepage
    http.ListenAndServe(":8080", nil)
}

func HomeHandler(w http.ResponseWriter, r *http.Request) {

    if (strings.Contains(r.URL.Path, ".")) {
        chttp.ServeHTTP(w, r)
    } else {
        fmt.Fprintf(w, "HomeHandler")
    }   
}
2020-07-02