NGINX hashbang rewrite

2019-06-17 00:48发布

I'm wondering what a location or rewrite nginx directive for hashbang (#!) urls would look like. Basically routing all non hash-banged url's through the hashbang like a front controller. So:

http://example.com/about/staff

would route to

http://example.com/#!/about/staff

I'm unclear what the best technique here would be? Whether writing an if statement to check existence of the hashbang, or just a generic rewrite that filters all requests...

3条回答
霸刀☆藐视天下
2楼-- · 2019-06-17 01:42

The best route is to use the try_files directive:

location {
    try_files $uri $uri/ /index.html;
}

Assuming your index.html file contains the javascript logic that routes the hash to the correct resource. The URI will remain what the visitor requested whereas Nginx simply routes the request to your index file when no real matching file can be found for the request uri.

查看更多
戒情不戒烟
3楼-- · 2019-06-17 01:43

GETs for fragment identifiers don't/shouldn't (some buggy clients may send them) appear in an HTTP request, so you can't have a rewrite rule to match them, regardless of webserver.

The HTTP engine cannot make any assumptions about it. The server is not even given it.

If you tried to make the initial request for / redirect to /#! rather than serving the root index, you'd end up with a "too many redirects" error, as the client would come back asking for / again (remember that it won't send the # with its request). You'll need to do this with javascript instead for the index document.

The bottom line is that it's not available server-side in the GET request. Even curl has been patched not to send it any more.

You could have nginx location directives to make everything else hit the front controller though:

 location = / {
  }      

  location = /index.html {
  }      

  location ~ / {
    rewrite ^ /#!$uri redirect;
    break;
  }

Beware of this approach though; http://jenitennison.com/blog/node/154 goes into a lot more detail about the hashbang debacle at Gawker and other issues surrounding its use.

查看更多
太酷不给撩
4楼-- · 2019-06-17 01:45

As a modification of the above, I only do this redirection for specific calls, and thusly get no potential loop backs:

location ~ /login|/logout|portfolios|/portfolio/*|/public/* {
  rewrite ^ /#!$uri permanent;
  break;
}

Note that this works fine on all browser except for Safari. Safari will redirect you to the url sans the hash.

查看更多
登录 后发表回答