2012-02-07 13 views
21

pushStateベースのURI処理でnginxを動作させようとしていますが、backbone.jsはJavascriptアプリケーションで私を管理しています。pushState-URLのためにnginxを書き直す

今は1つのレベルでURIにアクセスしています。 example.com/usersはうまく動作しますが、ないBackbone documentationに記載されている2レベルまたは深いURIのようなexample.com/users/all、:

たとえば、あなたは/文書/ 100、Webサーバ 必見のルートを持っている場合ブラウザがURL が直接

だから、nginxのの書き換えオプションに精通から遠く離れている、私はまだ私は私のindex.htmlにすべてをリダイレクトするようにrewrite^/index.html;ような何かを行うことができますことを確信していることを訪れた場合、そのページを提供することができます、しかしloosi私がアクセスできる必要がある同じサーバに格納されている最終的な静的ファイル(画像、javascript & css)にアクセスしないでください。

これを行うには、現在の設定ではなく、次に示すようにしてください。

server { 
    listen 80; 
    server_name example.com; 

    location/{ 
     root /var/www/example.com; 
     try_files $uri /index.html; 
    } 

} 

答えて

19

これは私のアプリケーションにしたものです。 (ルート、それ自身を除く) '/' で終わるすべてのルートがindex.htmlを提供します:

location ~ ^/.+/$ { 
    rewrite .* /index.html last; 
    } 

あなたはまた、あなたのルートの前に付けることができます。

Backbone.history.start({pushState: true, root: "/prefix/"}) 

、その後:

location ~ ^/prefix/ { 
    rewrite .* /index.html last; 
    } 

あるいは、それぞれのケースについてルールを定義します。

+3

、この場合のために、以下のスーツAJAX要求APIがあるかもしれないので、あなたの最初の提案は、最後のスラッシュを必要とするように見える...リライトは「/検索/」動作しますが、 "/ search"ではない – andrhamm

+1

後ろにスラッシュを付けていないとどうしたら解決できますか? –

+0

おそらく、index.html以外のものを受け入れる正規表現ですか? –

14

私はこのようにそれを管理:

#set root and index 
root /var/www/conferences/video/; 
index index.html; 

#route all requests that don't serve a file through index.html 
location/{ 
    if (!-e $request_filename){ 
     rewrite ^(.*)$ /index.html break; 
    } 
} 
+1

私はこれを使って500を得ました。 –

+0

この設定は私のために働く! – llazzaro

30

私は、このソリューションと一緒に行くことになった:

server { 

    listen 80; 
    server_name example.com; 
    root /var/www/example.com; 

    # Any route containing a file extension (e.g. /devicesfile.js) 
    location ~ ^.+\..+$ { 
     try_files $uri =404; 
    } 

    # Any route that doesn't have a file extension (e.g. /devices) 
    location/{ 
     try_files $uri /index.html; 
    } 

} 

この方法で、ファイルが見つからない場合は、少なくとも私はまだ適切な404エラーが発生します。クライアント側アプリケーションのパスで

+2

ありがとう、これは私のために働いた。実際の404が重要です。存在しないJSファイルが要求され、代わりにHTMLが返された場合、ブラウザはJSとして解析し、あらゆる種類のJSエラーをスローします。それはSPAを台無しにするかもしれない。 – ccnokes

+1

これは高くなるはずです。シンプルでエレガントなファイルと404は本当に重要です – Igonato

7

/ 
/foo 
/foo/bar 
/foo/bar/baz 
/foo/bar/baz/123 
/tacos 
/tacos/123 

使用:ルートレベルのルートとパスの

server { 
    listen 80; 
    server_name example.com; 
    root /var/www/example.com; 

    gzip_static on; 

    location/{ 
     try_files $uri $uri/ /index.html; 
    } 

    # Attempt to load static files, if not found route to @rootfiles 
    location ~ (.+)\.(html|json|txt|js|css|jpg|jpeg|gif|png|svg|ico|eot|otf|woff|woff2|ttf)$ { 
     try_files $uri @rootfiles; 
    } 

    # Check for app route "directories" in the request uri and strip "directories" 
    # from request, loading paths relative to root. 
    location @rootfiles { 
     rewrite ^/(?:foo/bar/baz|foo/bar|foo|tacos)/(.*) /$1 redirect; 
    } 
} 

@Adam-Waite's answer一方作品、位置コンテキスト内でアンチパターンであると考えられる場合に使用Apacheスタイルのディレクティブを変換するときによく見られます。参照:http://wiki.nginx.org/IfIsEvil

他の回答では、反応ルータとHTML5 pushStateを有効にした同様のReactアプリで、ユースケースのディレクトリの深さのあるルートはカバーされません。ルートがexample.com/foo/bar/baz/213123のような「ディレクトリ」内でロードまたはリフレッシュされると、index.htmlファイルは相対パスでjsファイルを参照し、example.com/js/app.jsではなくexample.com/foo/bar/baz/js/app.jsに解決されます。最初のレベルのような/foo/bar/bazを越えたディレクトリの深さの例については

は、@rootfilesディレクティブで宣言されたディレクトリの順序に注意してください。可能な限り最長のパスは次の浅いパス/foo/bar、最後に/foo続く、最初に行く必要があります。

0

私が行くとき

server { 
    listen 80; 
    server_name example.com; 
    root /var/www/example.com; 

    # Any route containing a file extension (e.g. /devicesfile.js) 
    location ~ ^.+\..+$ { 
     try_files $uri =404; 
    } 

    # Any route that doesn't have a file extension (e.g. /devices) 
    location/{ 
     try_files $uri /index.html; 
    } 

    # The location block above provides the shortest prefix, of length one, 
    # and so only if all other location blocks fail to provide a match, 
    # this block will be used. 

    # Ajax api starts with /v1/ will be proxied 
    location /v1/ { 
     proxy_pass http://proxy; 
    } 
} 
関連する問題