Go 웹 서버를 사용하여 정적 HTML 파일을 어떻게 제공합니까?


89

go 웹 서버를 사용하여 index.html (또는 다른 정적 HTML 파일)을 어떻게 제공합니까?

go 웹 서버에서 제공 할 수있는 기본적인 정적 HTML 파일 (예 : 기사 등)이 필요합니다. HTML 템플릿을 사용하는 경우처럼 HTML은 go 프로그램 외부에서 수정할 수 있어야합니다.

이것은 하드 코딩 된 텍스트 ( "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)
}

답변:


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에서 파일 제공

당신은 파일을 제공 할 경우, 폴더에서 말하는 ./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무엇입니까?
Bryce

파일이 완전히 프로젝트 외부의 하드 드라이브에있는 경우 정적 html 파일을 어떻게 제공합니까?
iamtoc

절대 경로 : / Users / username / path / to / file에서 시도했지만 성공적으로 동일하게 작동했습니다.
iamtoc

@Bryce, 전체 하위 트리를 일치 시키려고하기 때문입니다 ( 참조 ). 단지와 /static단지 패턴 (그리고 스트립 접두사)로 http://example.org/static요청이 파일 서버 핸들러에 의해 제공됩니다. 즉 http://example.org/static/, 및 http://example.org/static/foo.css기타에 대한 요청 이 실패하거나 다른 핸들러에 의해 처리됩니다.
maxschlepzig

나머지 경로와 함께 정적 파일을 제공 할 수 있습니까?

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렌더링을 원합니다 .

이것이 주로 " Writing Web Applications "가 설명하는 것과 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 2014 년

확인 @nairware, 나는 대답을 다시 한
VonC

그렇다면 Go에서 HTML 페이지와 서버 페이지를 사용하는 클래식 웹 사이트를 만들 수있는 방법이 없습니까? 정적 웹 사이트 여야합니까 아니면 템플릿 기반 웹 사이트 여야합니까?
Spero

0

이것은 golang에서 다음과 같이 쉽습니다.

package main

import (
    "log"
    "net/http"
)

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

`

이 작업을 수행하고 HTML 파일을 다음과 같이 유지하십시오. index.html

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.