提供静态文件时出现 golang 错误

标签 go go-templates fileserver go-html-template gopath

在执行模板时,我无法在go lang中找出这个错误

panic: open templates/*.html: The system cannot find the path specified.

另一个问题是我的公用文件夹无法从 css 提供,我不知道为什么。

代码:

package main

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

var tpl *template.Template

func init() {
    tpl = template.Must(template.ParseGlob("templates/*.html"))
}

func main() {
    r := mux.NewRouter()
    r.HandleFunc("/",home)
    http.Handle("/public/", http.StripPrefix("/public/", 
    http.FileServer(http.Dir("/pub"))))
    http.ListenAndServe(":8080", r)
}

func home(writer http.ResponseWriter, request *http.Request) {
    err := tpl.ExecuteTemplate(writer, "index.html", nil)
    if err != nil {
        log.Println(err)
        http.Error(writer, "Internal server error", http.StatusInternalServerError)
    }
}

我的文件夹是这样的:

bin
pkg
pub
   css
     home.css
   js
src
   github.com
        gorila/mux
templates
        index.html

my GOROOT is pointing to the folder project which contains the bin pkg src

when I make the templates folder outside src it works fine but I thinks that's not right everything must be in src right ?

index.html

    <!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>test</title>
    <link href="../public/css/home.css" type="text/css" rel="stylesheet" />
</head>
<body>
<h1>welcome! hi</h1>
</body>
</html>

这里我不能提供CSS

更新::

第一个问题解决了templates文件夹。

但是我还是解决不了第二个问题

最佳答案

我个人觉得标准http库对于此类任务非常好且简单。然而,如果你坚持使用 gorilla 的 mux这是我在您的代码中发现的问题:

func main() {
    ...
    http.Handle("/public/", http.StripPrefix("/public/", http.FileServer(http.Dir("/pub"))))
    http.ListenAndServe(":8080", r)
}

一方面,您正在使用 http.Handle提供静态文件,但另一方面你给rhttp.ListenAndServe .

要解决此问题,只需将该行更改为:

r.PathPrefix("/public/").Handler(
       http.StripPrefix("/public/",
           http.FileServer(http.Dir("/pub/"))))

如果可以的话,我想建议使用 flag为模板目录和公共(public)目录设置不同的路径,以便部署和运行您的服务器。

换句话说,您可以运行以下命令而不是对这些目录的路径进行硬编码:

./myserver -templates=/loca/templates -public=/home/root/public

为此只需添加以下内容:

import "flag"
....
func main() {
    var tpl *template.Template
    var templatesPath, publicPath string
    flag.StringVar(&templatesPath, "templates", "./templates", "Path to templates")
    flag.StringVar(&publicPath, "public", "./public", "Path to public")

    flag.Parse()
    tpl = template.Must(template.ParseGlob(templatesPath+"/*.html"))
    r.HandleFunc("/", handlerHomeTemplates(tpl))
    r.PathPrefix("/public/").Handler(http.StripPrefix("/public/", http.FileServer(http.Dir(publicPath))))
    ...
}

func handlerHomeTemplates(tpl *template.Template) http.HandlerFunc {
    return http.HandlerFunc(func((writer http.ResponseWriter, request *http.Request) {
        err := tpl.ExecuteTemplate(writer, "index.html", nil)
        if err != nil {
            ...
        }
    })
}

甚至想到了init function 是做其中一部分的好地方,我认为除非需要,否则最好避免使用它。这就是我在 main 中进行所有初始化的原因。功能和使用handlerHomeTemplates返回一个新的 http.HandleFunc使用templatesPath .

关于提供静态文件时出现 golang 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45899656/

相关文章:

swift - 如何使用 Kitura 设置 StaticFileServer()?

go - 在 Go 可执行文件中包含完整的目录结构,而不是单个文件

go - 在 Golang 中,我可以将 slice 值分配为返回值吗?

Powershell 主目录未在文件服务器文件系统上创建

golang代码插入/替换

html - 随机数未呈现的HTML模板

http - 为什么我的文件服务器处理程序不起作用?

go - 导航并添加到TabItem中的内容

datetime - 从Win32时代开始将纳秒添加到Go时间

arrays - 从golang模板调用数组的方法