2017-07-02 15 views
0

reactjsプロジェクトでreact-routerとbrowserHistoryのpushStateを使用しています。このプロジェクトでは、ユーザーが新しいパスを作成するノートを作成できます。このタイプのサイトを提供するには、静的コンテンツ以外のすべてのパスに同じHTMLファイルを提供する必要があります。だから私のnodejsコードはこのように見えます。Goで動的に作成されたURLパスをどのように提供するのですか?

// Serve the static content 
app.use('/static/css/', express.static(path.join(__dirname, '../../react-ui/build/static/css'))); 
app.use('/static/js/', express.static(path.join(__dirname, '../../react-ui/build/static/js'))); 
app.use('/static/media/', express.static(path.join(__dirname, '../../react-ui/build/static/media'))); 
app.use('/static/img/', express.static(path.join(__dirname, '../../react-ui/build/static/img'))); 
app.use('/img/', express.static(path.join(__dirname, '../../react-ui/build/img'))); 

// Serve the same HTML file to everything else 
app.use('*', express.static(path.join(__dirname, '../../react-ui/build'))); 

Go FileServerのワイルドカードサポートはありません。現在、私は静的なページをこのようなGoコードを使って提供しています。

package main 

import (
    "net/http" 
) 

func init(){ 
    fs := http.FileServer(http.Dir("web")) 
    http.Handle("/", fs) 
    http.Handle("/static-page-1/", http.StripPrefix("/static-page-1/", fs)) 
    http.Handle("/static-page-2/", http.StripPrefix("/static-page-2/", fs)) 
    http.Handle("/static-page-3/", http.StripPrefix("/static-page-3/", fs)) 
} 

Goサーバーで動的に生成されたURLパスにコンテンツを提供することは可能ですか?ハンドル方法は、変数をサポートしている場合

は、私はその中のユーザタイプは静的/パス/下にない任意の経路であろうこの

fs := http.FileServer(http.Dir("web")) 
http.Handle("/static/", fs) 
http.Handle("/{unknownUserPath}", http.StripPrefix("/{unknownUserPath}", fs)) 

{unknownUserPath}のよ​​うなコードを書くだろう。ここで

は、外出先のプロジェクト構造

enter image description here

はここ@putu答え

package main 

import (
    "net/http" 
    "strings" 
) 

func adaptFileServer(fs http.Handler) http.Handler { 
    fn := func(w http.ResponseWriter, req *http.Request) { 
     staticIndex := strings.Index(req.URL.Path, "/static/"); 
     imgIndex := strings.Index(req.URL.Path, "/img/"); 

     if staticIndex == -1 && imgIndex == -1 { 
      fsHandler := http.StripPrefix(req.URL.Path, fs) 
      fsHandler.ServeHTTP(w, req) 
     } else { 
      fs.ServeHTTP(w, req) 
     } 
    } 
    return http.HandlerFunc(fn) 
} 

func init() { 
    fs := http.FileServer(http.Dir("web")) 
    http.Handle("/", adaptFileServer(fs)) 
} 

答えて

1

URLパターン/*の静的コンテンツを特定のディレクトリに配信する場合は、jeevatkmの回答を使用します。

若干カスタマイズ可能なバージョンが必要な場合は、アダプターの種類が必要です。この場合、URLパスを静的ファイルハンドラー(http.FileServer)にマップします。コード例は次のようになり:上記アダプタの例で

package main 

import (
    "log" 
    "net/http" 
    "regexp" 
) 

func helloHandler(w http.ResponseWriter, r *http.Request) { 
    w.Write([]byte("Hello world!")) 
} 

func adaptFileServer(fs http.Handler, mux http.Handler) http.Handler { 
    fn := func(w http.ResponseWriter, req *http.Request) { 
     //Use your Path matcher here. 
     //For demonstration, REGEX match is used 
     //and it's probably not the most efficient. 
     staticRegex := regexp.MustCompile("^/static-page-[0-9]+/") 
     if matches := staticRegex.FindStringSubmatch(req.URL.Path); matches != nil { 
      log.Printf("Match: %v, %v", req.URL.Path, matches[0]) 
      fsHandler := http.StripPrefix(matches[0], fs) 
      fsHandler.ServeHTTP(w, req) 
     } else if mux != nil { 
      log.Printf("Doesn't match, pass to other MUX: %v", req.URL.Path) 
      mux.ServeHTTP(w, req) 
     } else { 
      http.Error(w, "Page Not Found", http.StatusNotFound) 
     } 
    } 
    return http.HandlerFunc(fn) 
} 

func init() { 
    //Usual routing definition with MUX 
    mux := http.NewServeMux() 
    mux.HandleFunc("/hello", helloHandler) 

    //"Dynamic" static file server. 
    fs := http.FileServer(http.Dir("web")) 
    http.Handle("/", adaptFileServer(fs, mux)) 
} 

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

、特定パターン(上記の例では/static-page-*/)へのリクエストパスが一致する場合、それはhttp.FileServerに渡されます。一致しない場合、マルチプレクサが指定されている場合はmux.ServeHTTPを呼び出します。それ以外の場合は、404エラーが返されます。

別のマッチングルールが必要な場合は、regexパターンを変更するか、カスタムマッチャーを使用してください。

注:
FileServermuxに同じハンドラインスタンスを使用しないでください。たとえば、http.Handleを呼び出す場合は、ルーティングを処理するためにhttp.DefaultServeMuxを使用します。 http.DefaultServeMuxadaptFileServerの2番目の引数として渡すと、無限の再帰で終了する可能性があります。

+0

ありがとう! muxサーバーオブジェクトなしでファイルサーバーを動作させることができましたが、サービスを追加したい場合は、それを使用する必要があります。私は私の質問に使用しているコードを追加しました – sissonb

0

http.FileServerに基づいてサーバがディレクトリから静的ファイルを提供するための良い選択ですよ、それはサブディレクトリだのです。

func main() { 
    http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static")))) 

    log.Println("Listening...") 
    if err := http.ListenAndServe(":8080", nil); err != nil { 
    log.Fatal(err) 
    } 
} 

それはhttp://localhost:8080/static/<path-to-file>経由/static/*ディレクトリとそのサブディレクトリ下のすべてのファイルを提供します。

ディレクトリ構造を設計し、1つ以上のファイルサーバーハンドラを介してマップします。


EDIT:

コメントに尋ねたよう。静的ファイルをルートとその下に提供します。

http.Handle("/", http.StripPrefix("/", http.FileServer(http.Dir("web")))) 

それはweb/*下のファイルは、ルート/から提供されることを意味します。

+0

その部分は動作していますが、私がしようとしているのは、http.Handle( "/ *"、http.StripPrefix( "/ *"、fs)) 'のようなものです。ワイルドカード。 – sissonb

+0

わかりました。明確にするために、ルート '/'を意味し、その下は静的ファイルを提供するためのものですか? – jeevatkm

+0

答えに加えて、見てみてください。 – jeevatkm

関連する問題