如何使用go web服务器提供静态html文件?

nai*_*are 66 go

如何使用go web服务器提供index.html(或其他一些静态HTML文件)?

我只想要一个基本的,静态的HTML文件(例如文章),我可以从go web服务器提供.HTML应该在go程序之外可以修改,就像在使用HTML模板时一样.

这是我的Web服务器,它只托管硬编码文本("Hello world!").

package main

import (
  "fmt"
  "net/http"
)

func handler(w http.ResponseWriter, r *http.Request) {
  fmt.Fprintf(w, "Hello world!")
}

func main() {
  http.HandleFunc("/", handler)
  http.ListenAndServe(":3000", nil)
}
Run Code Online (Sandbox Code Playgroud)

Jar*_*ema 121

使用Golang net/http包可以轻松完成这项任务.

你需要做的就是:

package main

import (
        "net/http"
)

func main() {
        http.Handle("/", http.FileServer(http.Dir("./static")))
        http.ListenAndServe(":3000", nil)
}
Run Code Online (Sandbox Code Playgroud)

假设静态文件位于static项目根目录中的文件夹中.

如果它在文件夹中static,您将进行index.html文件调用http://localhost:3000/,这将导致呈现该索引文件,而不是列出所有可用的文件.

此外,调用该文件夹中的任何其他文件(例如http://localhost:3000/clients.html)将显示该文件,由浏览器正确呈现(至少Chrome,Firefox和Safari :))

更新:提供不同于"/"的网址文件

如果你想提供文件,比如./publicurl下的文件夹:localhost:3000/static你必须使用附加功能:func StripPrefix(prefix string, h Handler) Handler像这样:

package main

import (
        "net/http"
)

func main() {
        http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("./public"))))
        http.ListenAndServe(":3000", nil)
}
Run Code Online (Sandbox Code Playgroud)

多亏了这一点,你的所有文件./public都可以使用localhost:3000/static

没有http.StripPrefix功能,如果你试图访问文件localhost:3000/static/test.html,服务器会查找它./public/static/test.html

这是因为服务器将整个URI视为文件的相对路径.

幸运的是,它可以通过内置函数轻松解决.

  • 为什么处理模式是`/ static /`not`/static`? (3认同)

jer*_*ack 19

我更喜欢http.ServeFile为此使用http.FileServer. 我想要禁用目录浏览,如果文件丢失,则正确的 404 以及一种特殊情况下索引文件的简单方法。这样,您只需将构建的二进制文件放到一个文件夹中,它就会提供与该二进制文件相关的所有内容。当然,如果您将文件存储在另一个目录中strings.Replacep则可以使用on 。


func main() {
    fmt.Println("Now Listening on 80")
    http.HandleFunc("/", serveFiles)
    log.Fatal(http.ListenAndServe(":80", nil))
}

func serveFiles(w http.ResponseWriter, r *http.Request) {
    fmt.Println(r.URL.Path)
    p := "." + r.URL.Path
    if p == "./" {
        p = "./static/index.html"
    }
    http.ServeFile(w, r, p)
}
Run Code Online (Sandbox Code Playgroud)

  • 对于复制粘贴此代码片段的人来说,上面的代码片段中存在一个“文件路径遍历”安全错误。它允许从服务器读取任意文件,请参阅https://owasp.org/www-community/attacks/Path_Traversal (9认同)

The*_*ool 13

如果您只想提供 1 个文件而不是完整目录,则可以使用http.ServeFile

http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
    http.ServeFile(w, r, "index.html")
})
Run Code Online (Sandbox Code Playgroud)


Von*_*onC 7

不是 FTP 服务器:这与我想要的不同,它是为index.html主页提供服务,就像普通的 Web 服务器一样。就像,当我在浏览器中访问 mydomain.com 时,我想要index.html渲染。

这主要是“编写 Web 应用程序”所描述的,以及像Hugo(静态 html 站点生成器)这样的项目所做的。

它是关于读取文件,并使用 ContentType "text/html" 进行响应:

func (server *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    err := server.renderFile(w, r.URL.Path)
    if err != nil {
        w.Header().Set("Content-Type", "text/html; charset=utf-8")
        w.WriteHeader(http.StatusNotFound)
        server.fn404(w, r)
    }
}
Run Code Online (Sandbox Code Playgroud)

renderFile()基本阅读和设置正确的类型:

 file, err = ioutil.ReadFile(server.MediaPath + filename)
 if ext != "" {
    w.Header().Set("Content-Type", mime.TypeByExtension(ext))
 }
Run Code Online (Sandbox Code Playgroud)