如何在Go服务器上运行html

I've created a server in Go and I'm trying to run an html file in the browser. But the browser just prints out the code like a txt file instead of rendering the html formatting. My index.html file is saved in the /public directory.

My go code looks like this:

package main

import (
    "net/http"
    "io/ioutil"
)

func main() {
    http.Handle("/", new(MyHandler))

    http.ListenAndServe(":8000", nil)
}

type MyHandler struct {
    http.Handler
}

func (this *MyHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
    path := "public/" + req.URL.Path
    data, err := ioutil.ReadFile(string(path))

    if err == nil {
        w.Write(data)
    } else {
        w.WriteHeader(404)
        w.Write([]byte("404 - " + http.StatusText(404)))
    }

}

In your main try using http.HandleFunc("/", ServeHTTP) then edit the ServeHTTP method so it doesn't have a reciever ie; func ServeHTTP(w http.ResponseWriter, req *http.Request)

You attempt to use that object and the Handle method may work fine too (if implemented correctly) but most of the examples use HandleFunc and if you do as well I bet your problem will go away.

The only other thing that would be causing the issues you're observing is a failure to read the file who's contents are assigned to data or some misconception about what the data in that file actually is.

Right now you're just reading the contents of the file and writing it out. Since Go can't tell what type of file it is, it can't set the header.

Thankfully, there's a useful http.ServeFile function in the net/http package that can help you.

func (this *MyHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
    path := "public/" + req.URL.Path
    http.ServeFile(w, r, filepath.Join("path/to/file", path))
}

http.ServeFile attempts to set the Content-Type based on the file extension or first handful of bytes (for a HTML file it should get it right).

A better solution is to make your route handler the http.FileServer

func main() {
    http.Handle("/", http.FileServer(http.Dir("./public"))

    http.ListenAndServe(":8000", nil)
}

Take a look at the examples in the Go docs for how to use it in other ways.

Shameless plug: I wrote a small middleware library that makes it a bit easier to serve static files in Go that you may find use in (or read just read the code for insight): https://github.com/elithrar/station

Start with getting the HTML up and running. Then, build in your HTTP error handling (e.g. 404). I recommend using the text/template from the start, even if you're not adding any dynamism to your app... yet!

package main

import (
    "io/ioutil"
    "log"
    "net/http"
    "text/template"
)

func main() {
    http.HandleFunc("/", RootHandler)

    if err := http.ListenAndServe(":8080", nil); err != nil {
        log.Fatal(err)
    }
}

func RootHandler(res http.ResponseWriter, req *http.Request) {
    file, _ := ioutil.ReadFile("public/index.html")
    t := template.New("")
    t, _ = t.Parse(string(file))

    t.Execute(res, nil)
}

In case you want to hold off on using the text/template package and just serve the HTML straight up, simply read your index.html file and write it to the response writer (e.g. res for response in my example, however many folks also use w for writer).

package main

import (
    "io/ioutil"
    "log"
    "net/http"
)

func main() {
    http.HandleFunc("/", RootHandler)

    if err := http.ListenAndServe(":8080", nil); err != nil {
        log.Fatal(err)
    }
}

func RootHandler(res http.ResponseWriter, req *http.Request) {
    file, _ := ioutil.ReadFile("public/index.html")
    res.Write(file)
}