Как открыть в Go-сервере статический HTML-файл по идентификатору в URL?
Как открыть в Go-сервере статический HTML-файл по идентификатору в URL? Типа по URL www.site.com/blog/t5544 открыть файл $/www/site.com/page10.html Такое вообще возможно?
Ответы (2 шт):
Возможно, конечно :)
Если я правильно понял, то нужно получить параметр из URL, открыть шаблон и передать туда этот параметр. Пакет net/http не умеет парсить URL, поэтому нужно будет воспользоваться внешним пакетом. Установим:
go get github.com/julienschmidt/httprouter
Меньше слов, больше примеров:
package main
import (
"fmt"
// Пакет net/http не умеет парсить параметры из URL, поэтому воспользуемся этим пакетом
"github.com/julienschmidt/httprouter"
"html/template"
"net/http"
)
type responseData map[string]interface{}
func main() {
// Создаем роутер
router := httprouter.New()
// Регистрируем пути
router.GET("/test", func(response http.ResponseWriter, request *http.Request, params httprouter.Params) {
_ = loadTemplate("test").Execute(response, responseData{})
})
// :id - и есть наш параметр
router.GET("/user/:id", func(response http.ResponseWriter, request *http.Request, params httprouter.Params) {
_ = loadTemplate("user").Execute(response, responseData{
"user_id": params.ByName("id"),
})
})
fmt.Println("We are alive on :8181")
_ = http.ListenAndServe(":8181", router)
}
// Можно прочитать файл и отдать его содержимое, а можно загрузить файл как шаблон, передать туда параметры
// и отдать пользователю
func loadTemplate(tpl string) *template.Template {
// Загружаем
return template.Must(template.ParseFiles(fmt.Sprintf("./page/%s.html", tpl)))
}
В test.html нет ничего интересного, а вот в user.html есть использование параметра:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
Страница пользователя с ID {{ .user_id }}
</body>
</html>
После запуска пройдем по адресу http://localhost:8181/user/100500
UPD. Вероятно, я неправильно понял вопрос, исправляюсь Отдать любой статичный файл, как подметили в комментарии, можно так:
package main
import (
"fmt"
"net/http"
)
func main() {
http.Handle("/", http.FileServer(http.Dir("static")))
fmt.Println("We are alive on :8181")
_ = http.ListenAndServe(":8181", nil)
}
В директории static размещаются файлы, которые должны быть доступны извне
type filesHandler struct {
// Таблица "ID файла" и положения на диске.
files map[string]string
}
func (h *filesHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
var f = h.files[r.RequestURI]
if f == "" {
http.NotFound(w, r)
return
}
http.ServeFile(w, r, f)
}