गो वेब सर्वर का उपयोग करके आप स्थैतिक HTML फ़ाइल की सेवा कैसे करते हैं?


91

गो वेब सर्वर का उपयोग करके आप index.html (या कुछ अन्य स्थिर HTML फ़ाइल) की सेवा कैसे करते हैं?

मुझे बस एक मूल, स्थिर HTML फ़ाइल (उदाहरण के लिए एक लेख की तरह) चाहिए, जिसे मैं एक वेब सर्वर से सेवा कर सकता हूं। HTML को गो कार्यक्रम के बाहर संशोधित किया जाना चाहिए, क्योंकि यह 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)
}

जवाबों:


145

गोलंग नेट / 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) उस फ़ाइल को दिखाएगा, ठीक से ब्राउज़र द्वारा प्रदान किया गया (कम से कम क्रोम, फ़ायरफ़ॉक्स और सफारी :))

अद्यतन: "/" से भिन्न url से फाइलें परोसी जा रही हैं

यदि आप फ़ाइलों की सेवा करना चाहते हैं, तो ./publicurl के अंतर्गत फ़ोल्डर से कहें : 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?
ब्रायस

यदि आप फ़ाइल को हार्ड-ड्राइव पर कहीं और रखते हैं, तो पूरी तरह से प्रोजेक्ट के बाहर एक स्थिर html फ़ाइल कैसे परोसें?
आईमटॉक

मैंने इसे निरपेक्ष पथ से लेने का प्रयास किया: / उपयोगकर्ता / उपयोगकर्ता नाम / पथ / से / फ़ाइल, और इसने सफलतापूर्वक वही काम किया।
आईमैटॉक

@ प्रयास करें, क्योंकि आप पूर्ण उप-मिलान ( यह भी देखें ) से मेल खाना चाहते हैं । केवल /staticपैटर्न (और स्ट्रिप-प्रीफ़िक्स) के रूप मेंhttp://example.org/static फ़ाइलस्वर हैंडलर द्वारा अनुरोध किया जाएगा। इसका मतलब है कि अनुरोध http://example.org/static/और http://example.org/static/foo.cssआदि विफल होगा या किसी अन्य हैंडलर द्वारा नियंत्रित किया जाएगा।
मैक्सक्लेपजिग

क्या बाकी मार्गों के साथ स्थिर फ़ाइलों की सेवा करना संभव है?
ब्रेन

15

मैं 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

एफ़टीपी सर्वर नहीं: जो मैंने इरादा किया था, उससे कुछ अलग है, जो index.htmlसामान्य वेब सर्वर की तरह, मुखपृष्ठ की सेवा के लिए होगा। जैसे, जब मैं अपने ब्राउज़र में mydomain.com पर जाता हूं, मैं index.htmlरेंडर करना चाहता हूं ।

यह मुख्य रूप से क्या है " राइटिंग वेब एप्लिकेशन " का वर्णन करता है, और ह्यूगो (स्टेटिक 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))
 }

शायद मैंने सवाल सही से नहीं पूछा। क्या यह एफ़टीपी सर्वर के समान फ़ाइल सर्वर के निर्माण का साधन प्रदान नहीं कर रहा है? यह मेरे इच्छित उद्देश्य से कुछ अलग है, जो सामान्य वेब सर्वर की तरह index.html होमपेज की सेवा के लिए होगा। जैसे, जब मैं अपने ब्राउज़र में mydomain.com पर जाता हूं, तो मुझे index.html प्रदान करना होता है। मैं वेब सर्वर के फ़ाइल सिस्टम पर संग्रहीत फ़ाइलों की निर्देशिका नहीं देखना चाहता। यदि मेरा प्रश्न भ्रामक था, तो मैं प्रश्न को पुनः संपादित करने के लिए संपादित कर सकता हूं।
nairware

@nairware ठीक है, मैंने उत्तर फिर से लिखा है
VonC

तो गो के तहत एक क्लासिक वेबसाइट बनाने का कोई तरीका नहीं है जो HTML पृष्ठों और सर्वर पृष्ठों का उपयोग करता है? यह या तो एक स्थैतिक वेबसाइट या एक टेम्पलेट-आधारित वेबसाइट होनी चाहिए?
स्पेरो

0

यह गोलंग में आसान है:

package main

import (
    "log"
    "net/http"
)

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

`

आप बस ऐसा कर सकते हैं और अपनी HTML फ़ाइल को रखना सुनिश्चित कर सकते हैं index.html


0

उदाहरण कैसे कस्टम एमपी 3 फ़ाइल सेवा:

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))
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.