Як ви обслуговуєте статичний файл HTML за допомогою веб-сервера go?


89

Як ви обслуговуєте index.html (або інший статичний файл HTML) за допомогою веб-сервера go?

Я просто хочу базовий статичний HTML-файл (наприклад, статтю, наприклад), який я можу обслуговувати з веб-сервера go. 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)
}

Відповіді:


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самим шаблоном (і префіксом strip) обробник FileServer обслуговує лише запити. Це означає, що запити до http://example.org/static/та http://example.org/static/foo.cssін. Будуть невдалими або оброблятимуться іншим обробником.
maxschlepzig

Чи можна обслуговувати статичні файли разом із маршрутами відпочинку?
Мозок

13

Я вважаю за краще використовувати 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)
}

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

Можливо, я не правильно поставив питання. Хіба це не є засобом побудови файлового сервера, подібного до FTP-сервера? Це щось інше, ніж те, що я мав на увазі, - це обслуговування домашньої сторінки index.html, як це робив би звичайний веб-сервер. Мовляв, коли я заходжу в mydomain.com у своєму браузері, я хочу, щоб відобразився index.html. Я не хочу бачити каталог файлів, що зберігаються у файловій системі веб-сервера. Я можу відредагувати питання, щоб переформулювати його, якщо моє питання вводило в оману.
nairware

@nairware гаразд, я переписав відповідь
VonC

Отже, немає можливості створити класичний веб-сайт під Go, який використовує сторінки HTML та сторінки сервера? Це має бути або статичний веб-сайт, або веб-сайт на основі шаблону?
Сперо

0

Це просто в голангу, як:

package main

import (
    "log"
    "net/http"
)

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

`

Ви можете просто зробити це і обов’язково зберегти файл HTML як index.html

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.