Go Golang to serve a specific html file

huangapple go评论81阅读模式
英文:

Go Golang to serve a specific html file

问题

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

在Go语言中,可以通过指定文件路径来提供html文件。类似于Flask中的render_template函数。

你可以像下面这样实现:

http.Handle("/hello", http.FileServer(http.Dir("static/hello.html")))

英文:
http.Handle("/", http.FileServer(http.Dir("static")))

Serves the html file in static directory.

Is there any way in Go that we can specify the html file to serve?

Something like render_template in Flask

I want to do something like:

http.Handle("/hello", http.FileServer(http.Dir("static/hello.html")))

答案1

得分: 43

也许使用自定义的http.HandlerFunc会更容易:

在你的情况下,你的函数将是http.ServeFile,用于仅提供一个文件。

参考“Go Web应用程序:提供静态文件”:

在你的主页处理程序下面添加以下内容(见下文):

http.HandleFunc("/static/", func(w http.ResponseWriter, r *http.Request) {
   // 不要这样做(见下文)
    http.ServeFile(w, r, r.URL.Path[1:])
})

这里使用了net/http包的ServeFile函数来提供我们的内容。实际上,任何以/static/路径开头的请求都将由此函数处理。我发现为了正确处理请求,我必须使用以下方式去掉前导的/

r.URL.Path[1:]

实际上,不要这样做。正如sztanpet评论中所说,在提交的9b67a5d中,这在Go 1.6中将不再可能:

如果提供的文件或目录名是相对路径,则相对于当前目录进行解释,并且可能上溯到父目录。如果提供的名称是由用户输入构建的,则在调用ServeFile之前应对其进行清理。作为预防措施,ServeFile将拒绝r.URL.Path包含“..”路径元素的请求。

这将防止以下“url”:

/../file
/..
/../
/../foo
/..\foo
/file/a
/file/a..
/file/a/..
/file/a\..
英文:

Maybe using a custom http.HandlerFunc would be easier:

Except in your case, your func would be the http.ServeFile one, for serving just one file.

See for instance "Go Web Applications: Serving Static Files":

> <del>Add the following below your home handler</del> (see below):

http.HandleFunc(&quot;/static/&quot;, func(w http.ResponseWriter, r *http.Request) {
   // do NOT do this. (see below)
    http.ServeFile(w, r, r.URL.Path[1:])
})

> This is using the net/http package’s ServeFile function to serve our content.
Effectively anything that makes a request starting with the /static/ path will be handled by this function.
One thing I found I had to do in order for the request to be handled correctly was trim the leading ‘/’ using:

r.URL.Path[1:]

Actually, do not do that.
This won't be possible in Go 1.6, as sztanpet comments, with commit 9b67a5d:

> If the provided file or directory name is a relative path, it is
interpreted relative to the current directory and may ascend to parent
directories
.
If the provided name is constructed from user input, it should be sanitized before calling ServeFile.
As a precaution, ServeFile will reject requests where r.URL.Path contains a ".." path element.

That will protect against the following "url":

/../file
/..
/../
/../foo
/..\\foo
/file/a
/file/a..
/file/a/..
/file/a\\..

答案2

得分: 7

你可以使用http.StripPrefix函数。

像这样:

http.Handle("/hello/", http.StripPrefix("/hello/", http.FileServer(http.Dir("static"))))
英文:

You could use http.StripPrefix

Like this:

http.Handle(&quot;/hello/&quot;, http.StripPrefix(&quot;/hello/&quot;,http.FileServer(http.Dir(&quot;static&quot;))))

答案3

得分: 1

也许我在这里漏掉了一些东西,但经过大量混乱的搜索,我整理了以下代码:

...

func downloadHandler(w http.ResponseWriter, r *http.Request) {
        r.ParseForm()
        StoredAs := r.Form.Get("StoredAs") // 文件名
        data, err := ioutil.ReadFile("files/" + StoredAs)
        if err != nil { fmt.Fprint(w, err) }
        http.ServeContent(w, r, StoredAs, time.Now(),   bytes.NewReader(data))
}

...

其中downloadHandler作为简单上传和下载服务器的一部分被调用:

func main() {
              http.HandleFunc("/upload", uploadHandler)
              http.HandleFunc("/download", downloadHandler)
              http.ListenAndServe(":3001", nil)
}   

在Firefox和Chrome中正常工作,甚至不需要文件类型。

英文:

Maybe I missed something here, but after a lot of confused searching, I put this together:

...

func downloadHandler(w http.ResponseWriter, r *http.Request) {
        r.ParseForm()
        StoredAs := r.Form.Get(&quot;StoredAs&quot;) // file name
        data, err := ioutil.ReadFile(&quot;files/&quot;+StoredAs)
        if err != nil { fmt.Fprint(w, err) }
        http.ServeContent(w, r, StoredAs, time.Now(),   bytes.NewReader(data))
}

...

Where downloadHandler is invoked as part of a simple upload and download server:

func main() {
              http.HandleFunc(&quot;/upload&quot;, uploadHandler)
              http.HandleFunc(&quot;/download&quot;, downloadHandler)
              http.ListenAndServe(&quot;:3001&quot;, nil)
}   

Works fine with Firefox and Chrome. Doesn't even need a file type.

huangapple
  • 本文由 发表于 2014年9月20日 13:21:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/25945538.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定