如何避免使用Go提供模板文件

如何避免使用Go提供模板文件,go,Go,我正在写一个小网站,我发现了一些问题,我不知道如何解决。所以 基本思想是为主题创建一个名为/themes/的文件夹,我们将在其中放置所有主题,例如经典,现代,等等。 目录树将如下所示: /themes/ classic/ index.html header.html footer.html css/ style.css js/ lib.js modern

我正在写一个小网站,我发现了一些问题,我不知道如何解决。所以 基本思想是为主题创建一个名为
/themes/
的文件夹,我们将在其中放置所有主题,例如
经典
现代
,等等。 目录树将如下所示:

/themes/
    classic/
        index.html
        header.html
        footer.html
        css/
            style.css
        js/
            lib.js
    modern/
        index.html
        header.html
        footer.html
        css/
            style.css
        js/
            lib.js
因此,我的http处理程序:

func main() {
    reloadConfig()

    http.HandleFunc("/", homeHandler)

    http.HandleFunc("/reloadConfigHandler/", reloadConfigHandler)

    // TODO: Theme loads html files also
    http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("themes/"+config.Theme+"/"))))
    http.ListenAndServe(":80", nil)
}
问题

问题是,如果我打开path
http://localhost/static/index.html
,因此我需要以下解决方案:

  • 拒绝
    /static/
    ,显示404
  • 拒绝
    /static/*.html
    ,显示404
  • 允许
    /static/{folder\u name}/{file\u name}
    这样以后我可以添加
    img
    文件夹或
    font
    文件夹,其中的内容将由服务器提供给客户端

  • 感谢您的建议。

    简单的方法是实现您自己的
    http.FileSystem

    type fileSystem struct {
        http.FileSystem
    }
    
    func (fs fileSystem) Open(name string) (http.File, error) {
        f, err := fs.FileSystem.Open(name)
        if err != nil {
            return nil, err
        }
    
        stat, err := f.Stat()
        if err != nil {
            return nil, err
        }
    
        // This denies access to the directory listing
        if stat.IsDir() {
            return nil, os.ErrNotExist
        }
    
        // This denies access to anything but <prefix>/css/...
        if !strings.HasPrefix(name, "/css/") {
            return nil, os.ErrNotExist
        }
    
        return f, nil
    }
    

    如何添加
    /static/css/
    /static/js/
    而不是
    /static/
    ?与您现在的做法相同,只需两次,并采用不同的路径。@ryan这是解决方案,但不灵活。。总有一天我会使用
    /css\u minified/
    ,也可能会添加
    /font/
    /images/
    或其他文件夹。这是一种解决方案,但不是优雅的方式。如果您能够将
    css
    js
    嵌套在另一个
    资产
    目录中,并将模板放置在
    模板
    (该部分是可选的),那么将模板和静态文件混合在$current_year=)中被认为是不优雅的,这也行。@Ryan将
    css
    js
    文件夹放入
    /assets/
    中也是个好主意。也许比为文件编写自己的处理程序更好。是的,这就是我需要的。谢谢请您解释一下,是否可以关闭从
    /static/index.html
    /static/
    的重定向。我不知道为什么会发生这种情况,但它是,只有index.html,但footer.html是可以的。在func中有什么方法可以解决这个问题吗?您必须包装http.FileServer返回的处理程序,并在那里捕获它。这不是通过
    http.FileSystem
    处理的,而是通过
    http.serveFile
    处理的。无论如何,你为什么会在乎?重定向在遵循它之后会导致404。
    fs := http.FileServer(fileSystem{http.Dir("themes/"+config.Theme+"/")})    
    http.Handle("/static/", http.StripPrefix("/static/", fs))