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

时间:2014-10-25 05:19:00

标签: go

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

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

这是我的网络服务器,它只托管硬编码文本(" 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)
}

8 个答案:

答案 0 :(得分:113)

使用Golang net / http包可以轻松完成任务。

您需要做的就是:

package main

import (
        "net/http"
)

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

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

如果它位于文件夹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功能,如果您尝试访问文件localhost:3000/static/test.html,服务器会在./public/static/test.html

中查找

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

幸运的是,它可以通过内置功能轻松解决。

答案 1 :(得分:4)

  

不是FTP服务器:这与我的意图不同,它可以像普通的Web服务器那样为index.html主页提供服务。比如,当我在浏览器中访问mydomain.com时,我希望index.html呈现。

这主要是" Writing Web Applications"描述了像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))
 }

答案 2 :(得分:1)

http.ServeFile相比,我更喜欢使用http.FileServer。我希望禁用目录浏览,如果文件丢失,则使用适当的404,以及一种特殊情况下索引文件的简便方法。这样,您可以将生成的二进制文件放到一个文件夹中,它将提供与该二进制文件有关的所有内容。当然,如果文件存储在另一个目录中,则可以在strings.Replace上使用p


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

答案 3 :(得分:0)

在golang中这很容易,因为:

package main

import (
    "log"
    "net/http"
)

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

`

您可以执行此操作,并确保将HTML文件保留为index.html

答案 4 :(得分:0)

示例如何自定义投放mp3文件:

r := http.NewServeMux()
r.HandleFunc("/file/*", func(w http.ResponseWriter, r *http.Request) {

    // Prepare file path
    pathFile := strings.ReplaceAll(r.RequestURI, "/file/", "./my_path/")
    f, err := os.Open(pathFile)
    if f == nil || err != nil {
        return
    }

    // Read file into memory
    fileBytes, err := ioutil.ReadAll(f)
    if err != nil {
        log.Println(err)
        _, _ = fmt.Fprintf(w, "Error file bytes")
        return
    }

    // Check mime type
    mime := http.DetectContentType(fileBytes)
    if mime != "audio/mpeg" {
        log.Println("Error file type")
        _, _ = fmt.Fprintf(w, "Error file type")
        return
    }

    // Custom headers
    r.Header.Add("Content-Type", "audio/mpeg")
    r.Header.Add("Cache-Control", "must-revalidate, post-check=0, pre-check=0")
    r.Header.Add("Content-Description", "File Transfer")
    r.Header.Add("Content-Disposition", "attachment; filename=file.mp3")
    r.Header.Add("Content-Transfer-Encoding", "binary")
    r.Header.Add("Expires", "0")
    r.Header.Add("Pragma", "public")
    r.Header.Add("Content-Length", strconv.Itoa(len(fileBytes)))
    http.ServeFile(w, r, pathFile)
})
log.Fatal(http.ListenAndServe(":80", r))

答案 5 :(得分:0)

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

http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
    http.ServeFile(w, r, "index.html")
})

答案 6 :(得分:0)

这会将 index.html 文件(如果您在根目录中)提供给 localhost:8080 上的浏览​​器

func main() {
    port := flag.String("p", "8080", "port to serve on")
    directory := flag.String("d", ".", "static file folder")
    flag.Parse()

    http.Handle("/", http.FileServer(http.Dir(*directory)))

    log.Printf("Serving %s on HTTP port: %s\n", *directory, *port)
    log.Fatal(http.ListenAndServe(":"+*port, nil))
}

答案 7 :(得分:0)

您还可以使用 Gorilla Mux 路由器来处理静态文件。 假设您在根目录中有一个静态文件夹和一个 index.html 文件。

import  "github.com/gorilla/mux"

  func main(){
    router := mux.NewRouter()
        fs := http.FileServer(http.Dir("./static/"))
        router.PathPrefix("/static/").Handler(http.StripPrefix("/static/", fs))
        log.Fatal(http.ListenAndServe(":8080", router))
}