Comment servir un fichier HTML statique à l'aide d'un serveur Web Go?

89

Comment servir index.html (ou un autre fichier HTML statique) à l'aide d'un serveur Web go?

Je veux juste un fichier HTML statique de base (comme un article, par exemple) que je peux servir à partir d'un serveur Web go. Le HTML doit être modifiable en dehors du programme go, comme ce serait le cas lors de l'utilisation de modèles HTML.

C'est mon serveur web qui héberge uniquement du texte codé en dur ("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)
}
nairware
la source

Réponses:

140

Cette tâche est très simple avec le package Golang net / http.

Tout ce que vous devez faire est:

package main

import (
        "net/http"
)

func main() {
        http.Handle("/", http.FileServer(http.Dir("./static")))
        http.ListenAndServe(":3000", nil)
}

en supposant que les fichiers statiques se trouvent dans le dossier nommé staticdans le répertoire racine du projet.

S'il est dans un dossier static, vous aurez un index.htmlappel de fichier http://localhost:3000/qui entraînera le rendu de ce fichier d'index au lieu de lister tous les fichiers disponibles.

De plus, l'appel de tout autre fichier de ce dossier (par exemple http://localhost:3000/clients.html) affichera ce fichier, correctement rendu par le navigateur (au moins Chrome, Firefox et Safari :))

MISE À JOUR: diffusion de fichiers à partir d'une URL différente de "/"

Si vous voulez servir des fichiers, dites à partir du dossier ./publicsous l'URL: localhost:3000/staticvous devez utiliser une fonction supplémentaire : func StripPrefix(prefix string, h Handler) Handlercomme ceci:

package main

import (
        "net/http"
)

func main() {
        http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("./public"))))
        http.ListenAndServe(":3000", nil)
}

Grâce à cela, tous vos fichiers ./publicsont disponibles souslocalhost:3000/static

Sans http.StripPrefixfonction, si vous essayez d'accéder au fichier localhost:3000/static/test.html, le serveur le recherche dans./public/static/test.html

Cela est dû au fait que le serveur traite l'URI entier comme un chemin relatif vers le fichier.

Heureusement, il est facilement résolu avec la fonction intégrée.

Jarema
la source
3
pourquoi le modèle de poignée n'est /static/pas /static?
Bryce
Comment servir un fichier html statique si le fichier est ailleurs sur le disque dur, entièrement en dehors du projet?
iamtoc
Je l'ai essayé à partir du chemin absolu: / Users / username / path / to / file, et cela a fonctionné avec succès tout de même.
iamtoc
@Bryce, car vous souhaitez faire correspondre le sous-arbre complet ( voir aussi ). Avec just /staticas pattern (et strip-prefix), seules les http://example.org/staticdemandes seraient servies par le gestionnaire FileServer. Cela signifie que les demandes à http://example.org/static/et http://example.org/static/foo.cssetc. échoueraient ou seraient gérées par un autre gestionnaire.
maxschlepzig
Est-il possible de servir des fichiers statiques avec des itinéraires de repos?
Brain
13

Je préfère utiliser http.ServeFilepour cela http.FileServer. Je voulais que la navigation dans les répertoires soit désactivée, un 404 approprié si des fichiers manquent et un moyen facile de cas particulier du fichier d'index. De cette façon, vous pouvez simplement déposer le binaire intégré dans un dossier et il servira tout ce qui concerne ce binaire. Bien sûr, vous pouvez utiliser strings.Replacesur psi vous avez les fichiers stockés dans un autre répertoire.


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)
}
jerblack
la source
5

PAS un serveur FTP: c'est quelque chose de différent de ce que je voulais, qui serait de servir la index.htmlpage d'accueil, comme le ferait un serveur Web normal. Par exemple, lorsque je vais sur mydomain.com dans mon navigateur, je veux un index.htmlrendu.

C'est principalement ce que décrit « Ecrire des applications Web », et ce que fait un projet comme hugo (générateur de site HTML statique).

Il s'agit de lire un fichier et de répondre avec un 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)
    }
}

avec renderFile()essentiellement la lecture et le réglage du bon type:

 file, err = ioutil.ReadFile(server.MediaPath + filename)
 if ext != "" {
    w.Header().Set("Content-Type", mime.TypeByExtension(ext))
 }
VonC
la source
Peut-être n'ai-je pas posé la question correctement. N'est-ce pas un moyen de créer un serveur de fichiers, similaire à un serveur FTP? C'est quelque chose de différent de ce que je voulais, qui serait de servir la page d'accueil index.html, comme le ferait un serveur Web normal. Par exemple, lorsque je vais sur mydomain.com dans mon navigateur, je veux que index.html soit rendu. Je ne veux pas voir un répertoire de fichiers stockés sur le système de fichiers du serveur Web. Je peux modifier la question pour reformuler si ma question était trompeuse.
nairware
@nairware ok, j'ai réécrit la réponse
VonC
Il n'y a donc aucun moyen de créer un site Web classique sous Go qui utilise des pages HTML et des pages serveur? Doit-il s'agir d'un site Web statique ou d'un site Web basé sur des modèles?
Spero
0

C'est facile en Golang car:

package main

import (
    "log"
    "net/http"
)

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

»

Vous pouvez simplement le faire et vous assurer de conserver votre fichier HTML sous index.html

Nishant Raj
la source