Как вы обслуживаете статический HTML-файл, используя веб-сервер Go?
Как вы обслуживаете index.html (или другой статический HTML-файл) с помощью веб-сервера go?
Мне просто нужен базовый статический HTML-файл (например, статья), который я могу обслуживать с веб-сервера. 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 ответов
Эта задача очень проста с пакетом 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:))
ОБНОВЛЕНИЕ: обслуживание файлов с URL, отличного от "/"
Если вы хотите обслуживать файлы, скажем, из папки ./public
под URL: 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 как относительный путь к файлу.
К счастью, это легко решается с помощью встроенной функции.
Я предпочитаю использовать 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)
}
Если вы хотите обслуживать только 1 файл, а не полный каталог, вы можете использовать http.ServeFile
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
http.ServeFile(w, r, "index.html")
})
НЕ FTP-сервер: это нечто отличное от того, что я намеревался, что бы служить
index.html
Домашняя страница, как обычный веб-сервер. Мол, когда я захожу на mydomain.com в моем браузере, я хочуindex.html
оказаны.
Это в основном то, что описывает " Написание веб-приложений", и то, что делает такой проект, как 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))
}
Вы также можете использовать Gorilla Mux Router для сервера статических файлов. Предположим, у вас есть статическая папка и файл 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))
}
Пример того, как пользовательский файл 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))
В голанге это просто:
package main
import (
"log"
"net/http"
)
func main() {
log.Fatal(http.ListenAndServe(":8080", http.FileServer(http.Dir("."))))
}
`
Вы можете просто сделать это и сохранить свой HTML-файл как index.html
Это будет обслуживать файл 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))
}