nginx try_files, pushState, and 404 - nginx

I'm trying to configure nginx to work with a pushState-enabled app. I've got it mostly working, but what I'm missing is getting a 404 returned on non-existent documents. How can I achieve this? Relevant part of my nginx.conf:
location / {
root /foo;
index index.html;
try_files $uri /index.html;
}
I've tried try_files $uri /index.html =404;, but that didn't work, obviously, because index.html exists.
I've also tried...
if (!-e $request_filename) {
return 404;
}
...in the server and location block. Neither worked.

Try this. If file exists, redirect to index.html. Otherwise return 404.
location = /index.html {}
location / {
if (!-f $request_filename) {
return 404;
}
rewrite ^/(.*) /index.html redirect;
}

Related

Nginx location regex not working for sub pages

I have two react applications, one at '/home/user/www' and one at '/home/user/builds/checkout'. I want any url starting with '/checkout' eg. '/checkout/complete', '/checkout/error' to use that application. I have the below setup in my Nginx config file:
root /home/user/www;
index index.html index.htm;
location / {
if (!-e $request_filename){
rewrite ^(.*)$ /index.html break;
}
}
location ~ ^/checkout?(.*)$ {
allow all;
root /home/user/builds;
if (!-e $request_filename){
rewrite ^(.*)$ /index.html break;
}
try_files $uri $uri/index.html =404;
}
location ~ ^.+\..+$ {
try_files $uri =404;
}
going to the url '/checkout' is working correctly but any other url begining with '/checkout' like '/checkout/complete' and 'checkout/error' are just returning a 404 page.
Your configuration looks too complicated. Can you try this one?
root /home/user/www;
index index.html index.htm;
location / {
try_files $uri /index.html;
}
location /checkout/ {
root /home/user/builds;
try_files $uri $uri/ /checkout/index.html;
}
If the /checkout URI won't redirect you to /checkout/, add this:
location = /checkout {
return 301 /checkout/;
}

How to fix ngnix.conf for redirect from .html and index.html

I want to do redirect from urls, real page exist here - mysite.com/folder/index.html :
mysite.com/folder/index.html to mysite.com/folder/
mysite.com/folder.html to mysite.com/folder/
mysite.com/index.html to mysite.com
This is part of my config
server_name k.my.net www.k.my.net;
index index.html;
root /var/www/demo/k.my.net/current/public;
rewrite ^(.*/)index\.html$ $1;
rewrite ^(/.+)\.html$ $1/;
location / {
try_files $uri $uri/ =404;
}
Also try do it with:
location / {
try_files $uri $uri/ #htmlext;
}
location ~ \.html$ {
try_files $uri =404;
}
location #htmlext {
rewrite ^(.*)$ $1.html permanent;
}
3-rd solution ERROR_LOOP
location ~* ^/([a-zA-Z1-9_-]*/)index\.html$ {
return 301 $1;
}
location ~* ^/([a-zA-Z1-9_-]*/?[1-9a-zA-Z_-]*)\.html$ {
return 301 /$1/;
}
location ~* ^/([a-zA-Z1-9_-]*/?[a-zA-Z1-9_-]*)/$ {
try_files /$1.html /$1/index.html =404;
}
You could use a regular expression location to extract the part of the URI before the trailing / and use try_files to test the two alternatives. See this document for details.
For example:
location ~ ^(.*)/$ {
try_files $1/index.html $1.html =404;
}
The location also matches / which will satisfy your third requirement.
Your rewrite statements should be safe, but if they cause redirection loops, you may need to replace them with an if block and test the original request in $request_uri. For example:
if ($request_uri ~ ^([^?]*?)(/index|)(\.html)(\?.*)?$) {
return 301 $1/$4;
}

Access index.html in folder without 301 redirect

I have some index.html files sitting in a folder to get some nice urls -
site.com/about
where index.html sits in the about folder. But I am seeing that my site.com/about is being 301 redirected to site.com/about/ I am not sure where the 301 is generated from. It is not in config.
/about/ also has a 301 result.
I guess it makes sense since I am redirecting to the index.html file but should it not be a rewrite? Is there a way to return 200 for /about instead of 301 to about/?
I am using nginx
Server Block:
server {
listen IP;
server_name site.com;
rewrite / $scheme://www.$host$request_uri permanent;
}
server {
listen IP:80;
server_name site.com *.site.com;
root /var/www/vhosts/site.com/htdocs;
charset utf-8;
rewrite_log on;
location / {
index index.html index.php;
try_files $uri $uri/ /$uri.php;
expires 30d;
}
if ($request_uri = /index.php) {
return 301 $scheme://$host;
}
if ($request_uri = /index) {
return 301 $scheme://$host;
}
location /. {
return 404;
}
location ~ .php/ {
rewrite ^(.*.php)/ $1 last;
}
include "ssl_offloading.inc";
location ~ .php$ {
# if (!-e $request_filename) { rewrite / /index.php last; }
if (!-e $request_filename) { rewrite / /404.php last; }
}
}
The index directive and the $uri/ element of the try_files directive, has the side-effect of adding a trailing / to directory names by performing an external redirect.
To avoid the external redirect and return an appropriate index file when presented with a slash-less directory name, implement the index functionality explicitly within the try_files directive:
location / {
try_files $uri $uri/index.html $uri.php;
expires 30d;
}
Notice that .php works only in the last element at this location. If you need to check for $uri/index.php (in addition to $uri.php) you can use a named location block - and move or copy your fastcgi configuration into it.
For example (based on your server block):
root /var/www/vhosts/site.com/htdocs;
error_page 404 /404.php;
location / {
try_files $uri $uri/index.html #php;
expires 30d;
}
location #php {
try_files $uri.php $uri/index.php =404;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
...
fastcgi_pass ...;
}
location = /index.php { return 301 $scheme://$host; }
location = /index { return 301 $scheme://$host; }
location /. { return 404; }
location ~* \.php(/|$) { rewrite ^(.*)\.php $1 last; }
include "ssl_offloading.inc";

Nginx Proxy_pass try_files drop to location handler

I'm running into small hick up with try_files in combination with proxy_pass (or alias for that matter).
Current config:
location /staticsrv {
alias /var/www/static/trunk/;
#proxy_pass http://static.localtest.nl/;
}
location ~ ^/staticsrv/images/gallery/(.*)$ {
try_files $uri #img_proxy;
}
location #img_proxy {
rewrite ^(.*)$ /index.php/?c=media&m=index&imag=$uri;
}
However for every file it gets dropped to the rewrite rule as it doesn't exist.
Is there a "trick" (read correct config) to fix my misfortune? Or is it just not possible? Both domains will eventually be on the same server so we can work with alias and proxy_pass.
Thanks in advance
Your location ~ ^/staticsrv/images/gallery/(.*)$ needs a root or an alias to construct a local path for try_files to try. Also, you do not necessarily need a regular expression here:
location /staticsrv/images/gallery/ {
alias /var/www/static/trunk/images/gallery/;
try_files $uri #img_proxy;
}
location #img_proxy {
rewrite ^ /index.php/?c=media&m=index&imag=$uri last;
}
proxy_pass will not work with try_files as one deals with remote content and the other with local content.
I try to avoid using alias and try_files in the same location block because of this open bug.
A possible work around would be to use another intermediate URI that closely matches the document root:
location /staticsrv/images/gallery/ {
rewrite ^/staticsrv(.+)$ /trunk$1 last;
}
location /trunk {
internal;
root /var/www/static;
try_files $uri #img_proxy;
}
location #img_proxy {
rewrite ^ /index.php/?c=media&m=index&imag=$uri last;
}

Nginx rewrites static files to index.html

I'm trying to work on a single page app - I need to rewrite all urls to index.html but allow existing static files (.css and .js) to be served as they normally would be in a browser.
This is the code that I'm trying to use to re-write but it serves my static files to the re-write as well
if (!-e $request_filename)
{
rewrite ^/(.*)$ /?/$1 last;
break;
}
you don't actually need a rewrite for that in nginx, just use try_files like so:
location / {
try_files $uri /index.html;
}
what this does is for all url's:
try the exact static filename match, and serve it if present
if 1 didn't serve anything, then server /index.html instead
see http://nginx.org/en/docs/http/ngx_http_core_module.html#try_files
This should work:
server {
listen 1.2.3.4:80;
server_name domain.eu;
root /usr/local/www/domain.eu/public;
try_files $uri #rewrites;
location #rewrites {
rewrite ^/favicon.ico$ /pictures/favicon.ico last;
rewrite ^ /index.html last;
}
}

Resources