2012-02-07 111 views
21

我想要nginx與我的pushState爲基礎的URI處理backbone.js在Javascript應用程序中管理我。重寫nginx pushState-URL的

現在訪問一個級別的URI,例如。 example.com/users效果很好,但不是兩個級別或更深的URI,如example.com/users/all,這是在Backbone documentation提到:

例如,如果您有/文件/ 100,Web服務器 必須的途徑能夠服務該頁面,如果瀏覽器訪問這個URL 直接

那麼,是遠遠不能用的nginx的重寫選項熟悉,我仍然相信,我可以這樣做rewrite^/index.html;一切重定向到我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

你的第一個建議似乎需要一個尾隨斜線...重寫工作,當我去「/搜索/」,但不是「/ search」 – andrhamm 2012-05-03 15:50:54

+1

如果你沒有斜線,你將如何解決它? – 2013-02-27 20:03:06

+0

也許是接受除index.html之外的任何東西的正則表達式? – 2013-02-27 20:03:37

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個使用這個。 – 2013-11-19 17:24:31

+0

這個配置適合我! – llazzaro 2014-08-21 04:17:15

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 2015-05-11 16:58:07

+1

這應該會更高。確實,簡單,優雅和404文件是非常重要的 – Igonato 2016-02-25 12:42:30

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

其他答案不包括使用react-router和HTML5 pushState啓用的類似React應用中的我的用例的目錄深度路由。當路徑在「目錄」(如example.com/foo/bar/baz/213123)內加載或刷新時,我的index.html文件將以相對路徑引用js文件並解析爲example.com/foo/bar/baz/js/app.js而不是example.com/js/app.js

對於超過第一級如/foo/bar/baz目錄深度的情況下,請注意@rootfiles指令聲明的目錄順序:最長的可能路徑需要去第一,其次是下一個較淺的路徑/foo/bar終於/foo

0

由於可能存在Ajax請求的API,對於這種情況下的西服,

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; 
    } 
}