Как вы обслуживаете статический html-файл с помощью веб-сервера Go?

89

Как вы обслуживаете index.html (или какой-либо другой статический HTML-файл) с помощью веб-сервера go?

Мне просто нужен базовый статический HTML-файл (например, статья), который я могу обслуживать с веб-сервера. HTML должен быть изменяемым вне программы go, как это было бы в случае использования HTML-шаблонов.

Это мой веб-сервер, на котором размещается только жестко закодированный текст («Привет, мир!»).

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)
}
Nairware
источник

Ответы:

140

Эта задача очень проста с пакетом 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 как относительный путь к файлу.

К счастью, это легко решается встроенной функцией.

Ярема
источник
3
почему рисунка ручки /static/нет /static?
Bryce
Как вы обслуживаете статический html-файл, если он находится в другом месте на жестком диске, вне проекта?
iamtoc
Я попытался сделать это с абсолютного пути: / Users / username / path / to / file, и он сработал так же успешно.
iamtoc
@Bryce, потому что вы хотите сопоставить полное поддерево ( см. Также ). С таким /staticже шаблоном (и полосой префикса) http://example.org/staticобработчик FileServer будет обслуживать только запросы. Это означает, что запросы к http://example.org/static/и http://example.org/static/foo.cssт. Д. Не будут выполняться или будут обработаны другим обработчиком.
maxschlepzig
Можно ли обслуживать статические файлы вместе с маршрутами отдыха?
Brain
13

Я предпочитаю использовать http.ServeFileдля этого http.FileServer. Я хотел отключить просмотр каталогов, правильный 404, если файлы отсутствуют, и простой способ особого случая индексного файла. Таким образом, вы можете просто перетащить встроенный двоичный файл в папку, и он будет обслуживать все, что связано с этим двоичным файлом. Конечно, вы можете использовать strings.Replaceon, 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)
}
джинсовый
источник
5

НЕ 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))
 }
VonC
источник
Возможно, я не правильно задал вопрос. Разве это не средство создания файлового сервера, подобного FTP-серверу? Это нечто иное, чем то, что я планировал, а именно обслуживание домашней страницы index.html, как это делал бы обычный веб-сервер. Например, когда я захожу на mydomain.com в своем браузере, я хочу, чтобы index.html отображался. Я не хочу видеть каталог файлов, хранящихся в файловой системе веб-сервера. Я могу изменить вопрос, чтобы перефразировать, если мой вопрос вводил в заблуждение.
nairware
@nairware хорошо, я переписал ответ
VonC
То есть нет возможности создать классический веб-сайт на Go, который использует HTML-страницы и серверные страницы? Это должен быть статический веб-сайт или веб-сайт на основе шаблона?
Spero
0

В голанге это просто:

package main

import (
    "log"
    "net/http"
)

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

`

Вы можете просто сделать это и сохранить свой HTML-файл как index.html

Нишант Радж
источник