How can i use NGINX try_files without changing the browser location for the client? - nginx

I am using nginx try_files for Server-Side-Rendering. Since GET-parameters affect the resulting html, i want to use try_files to check if i have a prerendered version with the matching query string (file is saved at /posts/?page=5/index.html)
I have the following try_files statement in place:
try_files $uri/$is_args$args/ $uri $uri/ #ssr;
This works, but the client gets redirected to www.page.com/posts/?page=5 which is including the slash of the subdirectory i have. This results in the browser getting a 404 in the end, because that post does not exist.
How can i use try_files like i did, but without actually redirecting the client? To be clear: I want to serve files from whereever with try_files, but not actually let the client know which file is served, thats none of the browsers business in my case.
Is there a way to achieve this?

Related

Nginx Reason for $uri/

I am looking at standard nginx server config for wordpress.
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
I understand the reason for $uri index.php$is_args$args
I do not understand the point of $uri/
I can see from nginx documentation "It is possible to check directory’s existence by specifying a slash at the end of a name, e.g. “$uri/”"
But I don`t get, what is the reason for returning a directory on request? Why would this be useful in a wordpress setup?
There is no such thing as "returning a directory on request". But trying to examine contents of a directory, and use them in order to satisfy a request - that's what it is here.
NGINX always has some non-empty value for the index directive (default is index.html), and that's essentially the files that NGINX will attempt to serve when trying a directory.
You don't really need $uri/ for WordPress if both conditions are met:
you don't have custom subdirectories/subsites which hold PHP files
you are using pretty permalinks
Removing $uri/ will result in saving one or more system stat calls (file existence check), so it is a performance improvement. The special case there would be a link /wp-admin. With try_files $uri /index.php$is_args$args it will be processed through /index.php, but Wordpress will do a proper redirect to /wp-admin/ (with slash).
And for what it's worth, you don't even need try_files if you have a habit of maintaining a well-structured website and intend to make it more optimized.

NGINX try_files works for all but one url

I have a simple dashboard for my site. Here is the directive:
location /dashboard {
try_files $uri /dashboard/index.php;
}
It works for all items after /dashboard. For example, /users or /pages - all CRUD operations work as expected.
The index.php file at /dashboard is my "controller". It parses the url and includes and runs scripts from there.
For example: /dashboard/group/edit/123456 works as expected and I get the edit page for group number 123456.
But when I post from that page to /dashboard/group/update, it serves /dashboard/group/index.php
So, in the first example, The edit page is loaded and the url at the top of the screen does not change.
In the second example, NGINX is CHANGING the url so my script cannot get the url parts to do the job.
I thought it may have something to do with POST, but I have other forms that use POST without issue.
In addition, or possibly a clue, try_files is returning /dashboard/group/index.php while the directive should return /dashboard/index.php.
Is there another NGINX file that could have so old code in it that is overwriting this domain's config?
I've been at this a few hours and have run out of ideas. Any thoughts?
* One More Clue *
When I BROWSE to /dashboard/group/update, NGINX shows the page as expected. It is only when I POST to that page that NGNIX sends me to /dashboard/group/index.php.
Again, at the very least, it should be sending me to /dashboard/index.php and NOT /dashboard/group/index.php.
You not send all after /dashboard try this:
location /dashboard {
try_files $uri /dashboard/index.php?$uri&$args;
}
OR
location /dashboard {
try_files $uri /dashboard/index.php?$query_string;
}
Nginx docs: https://nginx.org/en/docs/http/ngx_http_core_module.html#try_files
Instead of
location /dashboard {
try_files $uri /dashboard/index.php;
}
Try
location /dashboard {
index index.php; #adding this may work alone
try_files $uri /dashboard/index.php?$uri;
}
I have concluded that I have a cache problem. The location directive works on all items that I have not yet accessed.
So, my configuration - as described - works as it should.
I just have to figure out how to clear my cache ( which in NOT set up in NGINX that I can see!)
Thank you all who helped!

nginx Sinatra head meta refresh 404

For some reason, a page is forwarding to an nginx-served 404 page. The site is working except for this one page. On my landing page, I have the following in the header:
<meta http-equiv="refresh" content="5;URL=/second">
Even hard coding http://mydomain.local/second serves up the same 404.
This is a Sinatra deployment.
get "/second" do
#title = "my Title"
erb :index
end
I am thinking maybe my locations directive in nginx.conf is a bit screwy:
location / {
autoindex off;
try_files $uri $uri/ $uri/$request =404;
index /;
}
Anybody have any insight why Sinatra wouldn't capture the route and just serve up the file? Cheers.
Lets break this down:
autoindex off;
You don't need to specify this, it's off by default.
try_files $uri $uri/ $uri/$request =404;
Try and match requests to files in this order, serve the first one which matches. If none match, return 404. Your request is http://mydomain.local/second, so you are telling Nginx to look for:
webroot/second
webroot/second/
webroot/second/GET /second HTTP/1.1
Return 404
The index directive tells Nginx how to handle requests ending with a slash, you would normally specify files likely to be index files within your project, eg index.php, index.html etc. You don't really use this and try_files together as they serve a similar purpose.
Also worth noting that Nginx adds a trailing slash to any request which doesn't have one and doesn't end with a file extension, so it may also be the case that get "/second" do needs to change to get "/second/" do, as I doubt Sinatra ever sees the request without the trailing slash appended

double try_files directive for the same location in nginx

I discovered a nginx config snippet in serveral gists and config examples (mostly for PHP apps):
#site root is redirected to the app boot script
location = / {
try_files #site #site;
}
#all other locations try other files first and go to our front controller if none of them exists
location / {
try_files $uri $uri/ #site;
}
But I just do not get it: Does the first try_files directive ever match? To me this looks like some nonsense hacking.
Please confirm or explain why not - thanks :)
This is what happens here:
The first location = / is only used when the path in the request is /, e.g. http://example.com/. The second location /is used for all other URLs, e.g. http://example.com/foo or http://example.com/bar.
The reason for the first location is to avoid any interference from index-directives that do a redirect to index.html or something similar.
Inside the first location the try_files-directive first looks for a file named #site, which does not exist and then redirects to the named location #site. The reason for this construct is that the redirect to the named location is purely internal, i.e. the #site location can not be accessed directly from the client and the $uri is kept unmodified during this redirect (which would not be the case for other redirects). The first parameter #site can be anything except a real existing file. I prefer to call it DUMMY for clarity.
The second location tries static files first and, if not found, then also redirects to the named location.

View file with question mark in nginx

I've got some code that mirrors some pages using wget, and some of the pages to be mirrored are links like "http://example.com/somepage.php?id=1234". wget ends up saving those pages as "somepage.php?id=1234.html". When I try to visit that page, I get a 404.
I've tried adding "autoindex on;" to the config for that directory to make sure that the filename is correct, and I click on the link generated by nginx when I visit the directory that contains that page, and I still get a 404.
How can I get nginx to serve pages with a question mark in the name?
To future readers: visiting somepage.php%3Fid=1234.html worked. (See the comments above.)
Had this issue too, the solution was replacing try_files $uri with try_files $request_uri.
Or you could use both:
try_files $uri $request_uri =404;

Resources