Rewriting nginx for pushState-URL's

后端 未结 5 1994
再見小時候
再見小時候 2020-12-04 11:27

I am trying to get nginx to work with my pushState-based URI handling that backbone.js manages for me in an Javascript app.

R

相关标签:
5条回答
  • 2020-12-04 12:04

    I managed it like this:

    #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;
       }
    }
    
    0 讨论(0)
  • 2020-12-04 12:04

    With client side app paths:

    /
    /foo
    /foo/bar
    /foo/bar/baz
    /foo/bar/baz/123
    /tacos
    /tacos/123
    

    Use:

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

    While @Adam-Waite's answer works for the root and paths at the root level, using if within the location context is considered an antipattern, often seen when converting Apache style directives. See: http://wiki.nginx.org/IfIsEvil.

    The other answers do not cover routes with directory depth for my use case in a similar React app using react-router and HTML5 pushState enabled. When a route is loaded or refreshed within a "directory" such as example.com/foo/bar/baz/213123 my index.html file will reference the js file at a relative path and resolve to example.com/foo/bar/baz/js/app.js instead of example.com/js/app.js.

    For cases with directory depth beyond the first level such as /foo/bar/baz, note the order of the directories declared in the @rootfiles directive: the longest possible paths need to go first, followed by the next shallower path /foo/bar and finally /foo.

    0 讨论(0)
  • 2020-12-04 12:08

    I ended up going with this solution:

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

    This way, at least I still get proper 404 errors if a file isn't found.

    0 讨论(0)
  • 2020-12-04 12:11

    Since there may be ajax request api, the following suits for this case,

    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;
        }
    }
    
    0 讨论(0)
  • 2020-12-04 12:19

    Here is what i did to my application. Every route ending with a '/' (except the root it self) will serve index.html :

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

    You can also prefix your route :

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

    and then :

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

    Or define a rule for each case.

    0 讨论(0)
提交回复
热议问题