backbone.js 为pushState-URL重写nginx

8i9zcol2  于 2022-11-10  发布在  Nginx
关注(0)|答案(6)|浏览(190)

我正在尝试让nginxbackbone.js在Javascript应用程序中为我管理的基于pushState的URI处理一起工作。
现在,访问一个级别的URI(例如example.com/users)可以很好地工作,但访问两个级别或更深的URI(例如example.com/users/all)则不行,这在Backbone文档中有提及:

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

因此,虽然我还不太熟悉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;
    }

}
h79rfbju

h79rfbju1#

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

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错误,如果一个文件没有找到。

js5cn81o

js5cn81o2#

下面是我对我的应用程序所做的。每个以'/'结尾的路由(除了它自己的根)都将服务于index.html

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

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

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

然后:

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

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

oipij1gg

oipij1gg3#

我是这样处理的:


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

5cnsuln74#

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

/
/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应用中使用react-router和HTML5 pushState的用例,其他答案不包括具有目录深度的路由。当在一个“目录”(如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指令中声明的目录顺序:最长的可能路径需要首先通过,接着是下一个较浅的路径X1 M4 N1 X,最后是X1 M5 N1 X。

9avjhtql

9avjhtql5#

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

0yycz8jy6#

我尝试使用try_files $uri /index.html;,但nginx一直抱怨错误rewrite or internal redirection cycle while internally redirecting to "/index.html"
我喜欢亚瑟Xu提出的解决方案,但通过将所有 * 不 * 具有.的URL重写为/index.html来简化它。

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

上面的代码将所有不包含.的URL重写为/index.htm'

相关问题