重写nginx pushState-URL的

问题描述:

我想要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; 
    } 

} 

这是我对我的应用程序做了什么。以 '/' 结尾(除了根它的自我)每路线将成为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

我设法这样的:

#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

我结束了这个解决方案会:

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

使用客户端应用程序的路径:

/ 
/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

由于可能存在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; 
    } 
}