为pushState URL重写nginx';s

为pushState URL重写nginx';s,nginx,backbone.js,rewrite,pushstate,Nginx,Backbone.js,Rewrite,Pushstate,我试图让nginx使用基于pushState的URI处理,该URI处理在Javascript应用程序中由backbone.js为我管理 目前,使用一个级别(例如example.com/users)访问URI效果很好,但不能使用两个级别或更深层次的URI,例如example.com/users/all,这在以下内容中提到: 例如,如果您的路由为/documents/100,则您的web服务器 如果浏览器访问该URL,则必须能够为该页面提供服务 直接地 因此,我还不熟悉nginx的重写选项,我仍然确

我试图让
nginx
使用基于
pushState
的URI处理,该URI处理在Javascript应用程序中由
backbone.js
为我管理

目前,使用一个级别(例如
example.com/users
)访问URI效果很好,但不能使用两个级别或更深层次的URI,例如
example.com/users/all
,这在以下内容中提到:

例如,如果您的路由为/documents/100,则您的web服务器 如果浏览器访问该URL,则必须能够为该页面提供服务 直接地

因此,我还不熟悉nginx的重写选项,我仍然确信我可以做一些类似
rewrite^/index.html
将所有内容重定向到我的
index.html
,但最终会丢失存储在同一服务器上的所有静态文件(图像、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;
  }

或者为每个案例定义一个规则。

我是这样管理的:

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

我最终选择了这个解决方案:

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错误。

客户端应用程序路径:

/
/foo
/foo/bar
/foo/bar/baz
/foo/bar/baz/123
/tacos
/tacos/123
使用:

虽然在根级别对根和路径有效,但在位置上下文中使用if被视为反模式,在转换Apache样式指令时经常看到。请参阅:

其他答案不包括使用React router和启用HTML5 pushState的类似React应用程序中我的用例的目录深度路由。当在“目录”中加载或刷新路由时,例如
example.com/foo/bar/baz/213123
my 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;
    }
}

您的第一个建议似乎需要一个尾随斜杠。。。当我转到“/search/”而不是“/search”时,重写工作正常。如果没有尾随斜杠,您将如何解决它?我用这个得到了500。谢谢,这对我有用。拥有一个实际的404很重要——如果请求的JS文件不存在,而返回的是HTML,浏览器会尝试将其解析为JS并抛出各种JS错误。这可能会搞砸温泉浴场。这应该更高。简单、优雅和404对于文件来说确实很重要
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;
    }
}