21

我正在尝试nginx使用基于我pushState的 URI 处理,它backbone.js在 Javascript 应用程序中为我管理。

现在使用一级访问 URI,例如。example.com/users效果很好,但不是两级或更深的 URI,例如Backbone 文档example.com/users/all中提到的URI :

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

因此,远不熟悉 nginx 的重写选项,我仍然确信我可以做一些事情,比如rewrite ^ /index.html;将所有内容重定向到我index.html的 .能够访问。

那么我应该如何使用下面显示的当前配置来完成这项工作?

server {
    listen   80;
    server_name  example.com;

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

}
4

6 回答 6

33

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

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

于 2015-03-05T19:49:48.010 回答
19

这是我对我的应用程序所做的。每条以“/”结尾的路由(除了它自己的根)都将服务index.html

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

您还可以为您的路线添加前缀:

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

进而 :

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

或者为每种情况定义一个规则。

于 2012-02-08T13:22:54.527 回答
16

我是这样管理的:

#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;
   }
}
于 2013-08-06T09:54:26.007 回答
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 的答案适用于根级别的根和路径,但在位置上下文中使用 if 被认为是一种反模式,这在转换 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.

于 2015-05-28T19:08:52.317 回答
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;
    }
}
于 2016-05-04T15:06:02.483 回答
0

我试过了,try_files $uri /index.html;但 nginx 一直抱怨错误rewrite or internal redirection cycle while internally redirecting to "/index.html"

I liked the solution Arthur Xu presented, but simplified it by rewriting all URL't that don't have a . to /index.html.

  location / {
    rewrite ^[^.]+$ /index.html last;
    proxy_pass http://web:8080;
    ...

The above rewrites all URL's without . in them to /index.htm'.

于 2021-12-08T19:45:39.757 回答