英文:
golang return static html file at specified route
问题
我正在使用Go语言开发一个简单的待办事项应用程序。
我已经确定,除了用户的待办事项列表页面之外,所有页面都可以安全地作为静态HTML页面。
- 登录表单
- 新建账户表单
- 介绍待办事项应用程序的首页
目前我看不出这些页面需要使用Go模板的理由。
我的问题是,在Go语言中(不使用像nginx这样的工具),如何以最高效的方式将静态HTML设置为特定路由的返回值?
例如,将index.html返回给"/"路径。
我知道可以这样做:
func GetNewAccount(res http.ResponseWriter, req *http.Request) {
body, _ := ioutil.ReadFile("templates/register.html")
fmt.Fprint(res, string(body))
}
或者
var register, _ = string(ioutil.ReadFile("templates/register.html"))
func GetNewAccount(res http.ResponseWriter, req *http.Request) {
fmt.Fprint(res, register)
}
对我来说,这些方法似乎是更绕弯子的方式来实现一个看似简单的功能。
英文:
I am working on a simple todo app in go.
I have determined that all the pages except a user's list of todos can safely be a static html page.
- Login form
- new account form
- index page that talks about the todo app
I see no reason currently for these to be go templates.
My question is how (within go, not using something like nginx) can I have a static html set to return at a specific route most efficiently?
For example index.html to be returned at "/"
I know I could do something like:
func GetNewAccount(res http.ResponseWriter, req *http.Request) {
body, _ := ioutil.ReadFile("templates/register.html")
fmt.Fprint(res, string(body))
}
or
var register, _ = string(ioutil.ReadFile("templates/register.html"))
func GetNewAccount(res http.ResponseWriter, req *http.Request) {
fmt.Fprint(res, register)
}
To me these seems like more roundabout ways to do something seemingly simple.
答案1
得分: 10
如果您的静态文件都在同一目录下,您可以使用http.FileServer:
http.Handle("/s/", http.StripPrefix("/s/", http.FileServer(http.Dir("/path/to/static/files/"))))
否则,您可以在func init()
中将所需的HTML文件预加载到一个映射中,然后根据请求的路径使用fmt.Fprint
创建一个处理程序。
以下是一个简单的静态文件处理程序示例:
func StaticFilesHandler(path, prefix, suffix string) func(w http.ResponseWriter, req *http.Request) {
files, err := filepath.Glob(filepath.Join(path, "*", suffix))
if err != nil {
panic(err)
}
m := make(map[string][]byte, len(files))
for _, fn := range files {
if data, err := ioutil.ReadFile(fn); err == nil {
fn = strings.TrimPrefix(fn, path)
fn = strings.TrimSuffix(fn, suffix)
m[fn] = data
} else {
panic(err)
}
}
return func(w http.ResponseWriter, req *http.Request) {
path := strings.TrimPrefix(req.URL.Path, prefix)
if data := m[path]; data != nil {
fmt.Fprint(w, data)
} else {
http.NotFound(w, req)
}
}
}
然后您可以像这样使用它:
```go
http.Handle("/s/", StaticFilesHandler("/path/to/static/files", "/s/", ".html"))
英文:
If all your static files under the same tree, you could use http.FileServer:
http.Handle("/s/", http.StripPrefix("/s/", http.FileServer(http.Dir("/path/to/static/files/"))))
Otherwise pre-loading the html files you want into a map in func init()
then making one handler to fmt.Fprint
them based on the request's path should work.
Example of a simple static file handler :
func StaticFilesHandler(path, prefix, suffix string) func(w http.ResponseWriter, req *http.Request) {
files, err := filepath.Glob(filepath.Join(path, "*", suffix))
if err != nil {
panic(err)
}
m := make(map[string][]byte, len(files))
for _, fn := range files {
if data, err := ioutil.ReadFile(fn); err == nil {
fn = strings.TrimPrefix(fn, path)
fn = strings.TrimSuffix(fn, suffix)
m[fn] = data
} else {
panic(err)
}
}
return func(w http.ResponseWriter, req *http.Request) {
path := strings.TrimPrefix(req.URL.Path, prefix)
if data := m[path]; data != nil {
fmt.Fprint(w, data)
} else {
http.NotFound(w, req)
}
}
}
then you can use it like :
http.Handle("/s/", StaticFilesHandler("/path/to/static/files", "/s/", ".html"))
答案2
得分: -1
你可以使用第三方库来实现这个功能,类似这样的代码:
iris.StaticServe("/path/to/static/files","/theroute") //启用gzip压缩
上述代码片段是Iris的一部分。
英文:
Or just use third party library and do something like this:
iris.StaticServe("/path/to/static/files","/theroute") //gzip compression enabled
The above code snippet is part of the Iris
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论