For all pages in my codeigniter app except my default controller, main.php, when I refresh the browser the url isn't affected as one would expect.
However when I refresh the browser at "http://localhost/main", the main part is stripped off the url. So the browser bar shows just "http://localhost".
Totally lost on where to start with this but was just wondering if anyone has come across this before...?
Here's what I think could be the relevant part of my nginx.conf (if Nginx is the problem).
if ($request_uri ~* ^(/main(/index)?|/index(.php)?)/?$)
{
rewrite ^(.*)$ / permanent;
}
Note that changing the bracketed code to this:
rewrite ^(.*)$ /main permanent;
results in the error message The webpage at http://localhost/main has resulted in too many redirects.
Ok I answered my own question. Simply commenting out the nginx.conf code that I showed corrects the problem.
So just do this (says Bo Jackson):
#if ($request_uri ~* ^(/main(/index)?|/index(.php)?)/?$)
#{
# rewrite ^(.*)$ / permanent;
#}
If your trying to route your request to the index.php bootstrap so you can remove the index.php from your url in CodeIgniter you probably should try using this:
location / {
try_files $uri $uri/ /index.php?$query_string;
}
Related
I have a custom PHP application which follows the basic MVC pattern of development. The applications directory structure is as follows:
admin/
default/
index.php
In the admin is another index.php (which is how it handles requests to /admin).
In apache, this worked by putting a .htaccess file in each directory (admin and doc root) setting up a rewite and the application works. In NGINX, it doesnt seem so simple.
I can get the basic "default" application to work, by using this in my nginx.conf:
if (!-e $request_filename)
{
rewrite ^(.+)$ /index.php?path=$1 last;
}
(we run on vhosts so I cannot reference location / or I get a duplicate rule error).
This gets the frontend application to work, but when I try to access the /admin portion of the application the login screen loads, but when I try to submit and it tries to hit the endpoint 'admin/index/index' it fails, as my rewrite rule doesnt work. Here is what I have for the rewrite in NGINX:
location /admin {
try_files $uri $uri/ /admin/index.php?path=$uri&$args;
}
I think the issue is that the $uri being passed in is /admin/index/index instead of it being what it should be and is under Apache: /index/index.
Can anyone help me correct these NGINX rules so that my application works properly?
Thanks in advance.
As you said, you pass in the extra $uri. Try this:
location /admin {
try_files $uri $uri/ /admin/index.php?$args;
}
I have to support one old project which uses Yii1. I get very strange behavior. Pretty URL is configured.
When URL doen't have a trailing slash (e.g. /about or /blog/post/5) everything goes OK (the route is correct and the correct page is displayed). But the same URLs with trailing slash (/about/ or /blog/post/5/) make a wrong route. Disregarding of url I always get the route 'main/index' and index page is displayed (not redirected to, but displayed at all URLs with trailing slash).
Any ideas?
I had the same issue and the problem was in nginx config. Yii's pretty URLs require proper config to work. This was strange but the same config worked fine on one server and produced the described behavior on another server.
The problematic config:
location ~ ^(.+\.(js|css|jpeg|jpg|gif|png|ico|swf|mp3|html|eot|woff|ttf|otf|svg|zip|pdf|xml))$
{
rewrite ^(.*)/$ $1 permanent;
try_files $uri /index.php?$args;
}
The working config:
location /
{
index index.php;
if (!-e $request_filename)
{
rewrite ^/(.*) /index.php?r=$1 last;
}
}
We have a custom PHP application that we wrote and runs on Apache with .htaccess files to handle the url rewrites. We are trying to convert it to work under NGINX with FPM under Plesk Onyx.
The application generates links like:
https://somedomain.com/mypage (same as index/mypage)
https://somedomain.com/index/sitemap
https://somedomain.com/blog/some-article-name
These URL's map to index.php files that take the request_uri and use it to render the page responses.
The structure of the application is nested as follows:
docroot (/)
./index.php //handler for the request in /
./blog/index.php //handler for any request to /blog
Each index.php expects to receive a ?path={request_uri} so that it can map the request to the controllers and actions.
I have tried multiple ways to get NGINX to do this using tryfiles and rewrite, but no luck. Using rewrite I can get / to work, but it wont render /mypage or /index/sitemap.
If I try to hit /index/sitemap it downloads the index.php instead of executing it, and if I try the blog the same thing happens. In fact the only path that works is /, all others just download the index.php file.
Here is my configuration as it is now, where am I going wrong?
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
expires 30d;
add_header Pragma public;
add_header Cache-Control “public”;
try_files $uri #fallback;
}
location / {
#index index.php index.html index.html;
rewrite ^/([^?]*) /index.php?path=$1 break;
rewrite ^blog/([^?]*) /blog/index.php?path=$1 break;
#try_files $uri #fallback;
}
Your configuration has multiple issues. I will ignore the first location block as it seems to have nothing to do with your question.
The first rewrite will always match, so the second rewrite will never be consulted. The second rewrite will never match anyway, as nginx URIs always begin with a /. The [^?] is meaningless, because rewrite uses a normalised URI which does not include the ? or query string. Using rewrite...break means that the rewritten URI is processed within the same location, which is an error as this location is not equipped to process PHP files. See this document for more.
A solution using try_files might look like this:
location / {
try_files $uri $uri/ /index.php?path=$uri&$args;
}
location /blog {
try_files $uri $uri/ /blog/index.php?path=$uri&$args;
}
location ~ \.php$ { ... }
See this document for more.
I am running a joomla 2.5 site on ubuntu server with php/nginx/mysql (fairly new to nginx)
My problem is that when a user hits a url, I need it to ignore the .html file extension.
For example, if you hit mysite.com/page then it renders the page fine.
If you hit mysite.com/page.html then it will throw a 404 error. Which is because there isn't actually a 'page.html' page on my site. Its a K2 article alias. Yes, I could not put .html in but its not me adding content to the site, its the client. I have recently moved server and before it worked fine, now it doesnt so I know I have missed something in the config.
I know I can get nginx to do the opposite of what I want, with try files. Not sure how to get it to do the reverse.
This is my nginx config:
location / {
# First attempt to serve request as file, then
# as directory, then fall back to index.html
try_files $uri $uri/ /index.php;
# Uncomment to enable naxsi on this location
# include /etc/nginx/naxsi.rules
}
Now I know if i had a page.html page and I wanted to hide the .html I could add $uri.html
What I want to know is how to get nginx to try page.html if it cant find it try page
So turned out to be a Joomla Config variable. Under SEO settings in global config set 'apply suffix' to yes. I feel quite stupid. Thanks to all those that tried to help, as always much appreciated.
Here's a potential solution I managed to come across:
location / {
# If /{foo} is not an existing file or directory, rewrite to /{foo}.html
if (!-e $request_filename) {
rewrite ^(.+)$ /$1.html break;
}
# Redirect all {foo}.html URLS to /{foo}
rewrite ^/(.*)\.html$ /$1 redirect;
}
If you can correctly write .htaccess rewrite lines, try using a htaccess-to-nginx converter
As commented, this will check for the existence of a directory, file, etc. using the current URL. If nothing exists, it will attempt to request the url with .html appended.
Additionally, if .html is already present in the URL, it will redirect to the URL without .html
Quick workaround:
rewrite ^(. *)\.html$ $1 break;
Should be the first rewrite in the stack, even before try_files.
I want any requests like http://example.com/whatever/index.php, to do a 301 redirect to http://example.com/whatever/.
I tried adding:
rewrite ^(.*/)index.php$ $1 permanent;
location / {
index index.php;
}
The problem here, this rewrite gets run on the root url, which causes a infinite redirect loop.
Edit:
I need a general solution
http://example.com/ should serve the file webroot/index.php
http://example.com/index.php, should 301 redirect to http://example.com/
http://example.com/a/index.php should 301 redirect to http://example.com/a/
http://example.com/a/ should serve the index.php script at webroot/a/index.php
Basically, I never want to show "index.php" in the address bar. I have old backlinks that I need to redirect to the canonical url.
Great question, with the solution similar to another one I've answered on ServerFault recently, although it's much simpler here, and you know exactly what you need.
What you want here is to only perform the redirect when the user explicitly requests /index.php, but never redirect any of the internal requests that end up being served by the actual index.php script, as defined through the index directive.
This should do just that, avoiding the loops:
server {
index index.php;
if ($request_uri ~* "^(.*/)index\.php$") {
return 301 $1;
}
location / {
# ...
}
}
Try that
location ~ /*/index.php {
rewrite ^/(.*)/(.*) http://www.votre_domaine.com/$1 permanent;
}
location /index.php {
return 301 http://www.example.com/;
}
If you already have first line mentioned below in your Nginx configuration file you don't have rewrite it again.
index index.php index.html index.htm;
rewrite ^(/.).html(?.)?$ $1$2 permanent;
rewrite ^/(.*)/$ /$1 permanent;
try_files $uri/index.html $uri.html $uri/ $uri =404;
This will remove .html from the URL and additionally will also remove "index" from home page or index page. For example -
https://www.example.com/index will be changed to https://www.example.com
Try
location = /whatever/index.php {
return 301 $scheme://www.example.com/whatever/;
}
Another benefit from doing it this way is that nginx does a return faster than a rewrite.