如何使用Go Web服务器提供静态html文件?


89

如何使用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)
}

Answers:


140

使用Golang net / http包,该任务非常容易。

您需要做的只是:

package main

import (
        "net/http"
)

func main() {
        http.Handle("/", http.FileServer(http.Dir("./static")))
        http.ListenAndServe(":3000", nil)
}

假定静态文件位于static项目根目录中命名的文件夹中。

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

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

更新:从不同于“ /”的网址提供文件

如果您想为文件,从文件夹说./public下网址: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)
}

因此,您的所有文件./public都可以在localhost:3000/static

没有http.StripPrefix功能,如果您尝试访问file localhost:3000/static/test.html,服务器将在其中查找./public/static/test.html

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

幸运的是,使用内置函数可以轻松解决该问题。


3
为什么/static/没有处理模式/static
布莱斯

如果文件完全位于项目外部,则如何为静态html文件提供服务?
iamtoc '18 -10-20

我从绝对路径/ Users / username / path / to / file尝试了此操作,并且同样成功地工作了。
iamtoc '18 -10-20

@Bryce,因为您要匹配完整的子树(另请参见)。与/static模式(和带前缀)一样,仅http://example.org/staticFileServer处理程序将处理请求。这意味着对http://example.org/static/http://example.org/static/foo.css等的请求将失败或由另一个处理程序处理。
maxschlepzig

是否可以将静态文件与其余路由一起提供?
Brain

13

我更喜欢使用http.ServeFilehttp.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)
}

5

不是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)
    }
}

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

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

也许我没有正确地提出这个问题。这不是提供一种类似于FTP服务器的文件服务器构建方法吗?这与我的预期有所不同,后者将像普通的Web服务器一样为index.html主页提供服务。就像,当我在浏览器中转到mydomain.com时,我希望呈现index.html。我不想看到存储在Web服务器文件系统上的文件目录。如果我的问题有误导性,我可以将问题编辑为改写。
nairware 2014年

@nairware好的,我已将答案重写了
VonC

因此,有没有办法在Go下创建使用HTML页面和服务器页面的经典网站?它必须是静态网站还是基于模板的网站?
Spero

0

在golang中这很容易,因为:

package main

import (
    "log"
    "net/http"
)

func main() {
    log.Fatal(http.ListenAndServe(":8080", http.FileServer(http.Dir("."))))
}

`

您可以这样做,并确保将HTML文件保留为 index.html

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.