How to create SEO url for Nginx - .htaccess

I'm having issues converting the below htaccess rules to nginx. My site is written in PHP.
RewriteEngine On
RewriteRule ^([a-zA-Z0-9-/]+).html$ fullstory.php?url=$1
RewriteRule ^([a-zA-Z0-9-/]+).html/$ fullstory.php?url=$1
What I'm trying to do is convert this URL http://example.com/blog/fullstory.php?url=african-vegetable-recipe.html to http://example.com/blog/african-vegetable-recipe.html
OR
Get "african-vegetable-recipe.html" from example.com/blog/african-vegetable-recipe.html and use as a query string.
Can nginx handle this?

Are you using php-fpm? If so then you do not need to spend time re-writing the url. In Nginx, you have control over what parameters get passed to PHP.
The following Nginx location block will pass all matching requests to fullstory.php, the original request will still appear in the $_SERVER['REQUEST_URI'] where you can parse it for any information you require without needing to change your Rewrite rules in future.
location ~* ^([a-zA-Z0-9-/]+).html$ {
include fastcgi_params;
fastcgi_param DOCUMENT_ROOT /var/www/html/;
fastcgi_param SCRIPT_FILENAME /var/www/html/fullstory.php;
fastcgi_pass php-fpm;
}
The exact path to fullstory.php obviously needs changing to match your own system.
Alternately. To pass the bracketed part of the regexp into PHP as part of the query string. Use this statement in your server {} block.
rewrite ^([a-zA-Z0-9-/]+).html /fullstory.php?url=$1;

Related

.htaccess Implement domain name without port access service

You want to use the. Htaccess file to implement the service that accesses the specified port when there is' API 'in the path
The type is the same as nginx:
location /api/ {
proxy_pass http://localhost:8385;
}
In .htaccess you would need to use mod_rewrite in order to send the request through mod_proxy. The following is the equivalent of the Nginx config as posted:
RewriteEngine On
RewriteRule ^api/ http://localhost:8385%{REQUEST_URI} [P]
However, you will likely need access to the server config in order to ensure that mod_proxy (and associated modules are installed).
And, if you have access to the server config, then it would be preferable to do this in the main server config to begin with. For example:
ProxyPass /api/ http://localhost:8385/api/
ProxyPassReverse /api/ http://localhost:8385/api/

Convert htaccess file to nginx try_file for subfolder

RewriteEngine On
RewriteRule ^([^\.]+)$ $1.html [NC,L]
How to convert apache .htaccess file to nginx try_file?
I have static html files in the following folder structure and accessing them with pretty URL style without .html extensions it was working with apache but when I try to convert nginx config it was throwing 404 for subfolders. I used https://winginx.com/en/htaccess site for conversion.
# nginx configuration
location / {
rewrite ^/([^\.]+)$ /$1.html break;
}
+ root-folder
+ index.html - url - www.hello.com
+ abc.html - url - www.hello.com/abc
+ .........
+ xyz.html - url - www.hello.com/xyz
+ category-folder
+ category1.html - url - www.hello.com/category-folder/category1
+ category2.html - url - www.hello.com/category-folder/category2
+ category3.html - url - www.hello.com/category-folder/category3
+ page-folder
+ page1.html - url - www.hello.com/page-folder/page1
+ page2.html - url - www.hello.com/page-folder/page2
+ page3.html - url - www.hello.com/page-folder/page3
Any help will be really apricated.
The try_files is a good directive for front-controller patterns of dynamic frameworks powered by PHP or other languages, where you have a single bootstrap file, e.g. /index.php, which "serves" the SEO friendly URLs:
/foo/ -> /index.php
/bar/ -> /index.php
/lorem/ipsum -> /index.php
If your files are static and you know the file structure in advance, try_files brings nothing other than the performance penalty of stat (file existence check) system calls.
E.g. applying try_files $uri $uri.html $uri/ =404; from a comment by Richard, would mean that for URI /category-folder/category1, NGINX first checks that actual file /category-folder/category1 exists first, then checks if /category-folder/category1.html exists, and in case it doesn't, check if /category-folder/category1/ directory exists.
It makes much sense to stick to rewrite and converting configuration, in this case, is pretty straightforward. It will result in 1:1 match on how it worked in Apache.
Using my "fairly sophisticated" Apache to NGINX config converter, which does detect when you need to use try_files and when not, you will get the desired rewrite (place this directly in server context, not in location):
rewrite ^/([^\.]+)$ /$1.html last;
To check this rewrite you can use this test.
As you see, the only trick there is that URIs in NGINX rewrites (and URIs specified in NGINX in general) have to start with slash, whereas in Apache they are omitted.

Nginx duplicating query string on redirect

I am trying to redirect all traffic from urls that contain 'www.' to the similar url that does not contain it, but when I do so Nginx appends a duplicate query string at the end of the url.
For example, the user enters:
www.website.com/test/?_id=12345
And they get redirected to:
website.com/test/?_id=12345?_id=12345
Here is my config:
server {
server_name www.website.com;
return 301 $scheme://website$request_uri permanent;
}
server {
server_name website.com
# actual server stuff
}
I have tried appending a '?' to the end of the redirect after the 'request_uri' portion because form what I have read that should work, but it didn't.
Your config is invalid. You seem to have mixed up the syntax of return and rewrite. See this document for details.
The $request_uri variable already includes the query string, so this should work with return:
return 301 $scheme://example.com$request_uri;
The rewrite directive will append the query string unless a ? is appended. It is possible to use a rewrite directive to accomplish the same function, but in this case it would be overkill.
As your config is invalid, nginx is still running with an earlier configuration, possibly an earlier experiment that placed $request_uri in a rewrite directive, hence the double query string.

Nginx rewrite non-existent files under sub directory with rewrite rules

Nginx rewrite from .php to .php under same location
I am trying to move a site with a large number (93) of .htaccess files from Apache to Nginx.
There are over 800 rewrite rules to convert. To optimize performance, I have decided to
place the rules under separate nested location blocks (61 blocks in total).
But I am having problem with rewriting some of the rules.
Requirements:
/test/abc/pics/ should redirect to /test/abc/wallpapers/
/test/abc/pics/800/a.jpg should be served directly, if the file is present. If it does not exist,
then the request should be rewritten to /test/abc/pics/pic.php, which will
create the file on first request. Subsequent requests will be served directly.
/test/abc should redirect to /test/abc.html
/test/abc.html should be rewritten to /test/index.php
/test/abc/def/year-2014.php should be rewritten to /test/abc/def/index.php
All static files (.gif, .jpg, .png, .mpg....) should be served directly with a very long expiry time.
All files ending in .html should be served directly. If the file does not exist the request should be rewritten to /fallback.php
All files ending in .php or / should be executed by PHP-FPM. If the file does not exist it should be rewritten to /fallback.php
Config:
index index.php;
#
# Location Specific Rules
#
location /test/abc/ {
location /test/abc/pics/ {
# For ensuring 'serve directly, if file exists' condition of Rule 2
try_files $uri #rewrite_pics;
}
location /test/abc/def/ {
try_files $uri $uri/index.php #rewrite_def;
}
}
location /test/ {
rewrite "^/test/([a-z-]+)$" /test/$1.html permanent; # Rule 3
rewrite "^/test/([a-z-]+).html$" /test/index.php?symbol=$1 last; # Rule 4
}
location #rewrite_pics {
rewrite "^/test/abc/pics/$" /test/abc/wallpapers/ permanent; # Rule 1
rewrite "^/test/abc/pics/([0-9]+)/(.*)$" /test/abc/pics/pic.php?width=$1&height=$1&pic=$2 last; # Rule 2
}
location #rewrite_def {
rewrite "(?i)^/test/abc/def/year-([a-z]+).php$" /test/abc/def/index.php?year=$1 last;
}
#
# Fallback Rules
#
location ~* \.(gif|jpg|jpeg|png|ico|3gp|flv|mpg|mpeg|mp4|mp3|swf|txt|xml|pdf|zip)$ {
expires 1M; # Rule 5
try_files $uri /404.php;
}
location ~ (\.php|\.html|/)$ {
try_files $uri "${uri}index.php" /fallback.php =404;
include php-fpm.conf;
}
php-fpm.conf
include fastcgi.conf;
fastcgi_index index.php;
fastcgi_pass 127.0.0.1:9000;
Problem:
Since the fallback rules are regular expressions, they are selected instead of the location specific rules
If I use ~ prefix for all location specific rules, then the fallback rules are never executed.
Request for /test/abc/pics/800/a.jpg will be rewritten to /test/abc/pics/pic.php which will again match the
same location config. So the file is not executed and is downloaded as is.
So, I added 'include php-fpm.conf;' to all location blocks (except named locations). But this causes all
requests under /test/abc/pics/ (including existing .jpg files) to pass to the PHP-FPM. Which leads to an access denied error,
since only .php extension is allowed by security.limit_extensions.
What am I doing wrong here? Is there a simple way to have all existing files served based on their extension
and only non existent files match the location blocks / rewrite rules?

Nginx rewrite rules with try_files

I need help to converting this .htaccess to Nginx. Here is the .htaccess code:
RewriteRule wp-content/thesis/skins/(.*)/css.css wp-admin/admin-post.php?action=thesis_do_css
I already convert those rules to online nginx converter. So far I get this code:
rewrite /wp-content/thesis/skins/(.*)/css.css /wp-admin/admin-post.php?action=thesis_do_css;
I put those code above under try_files rules. Here is the complete code:
location / {
try_files $uri $uri/ /index.php?q=$uri$is_args&$args;
rewrite /wp-content/thesis/skins/(.*)/css.css /wp-admin/admin-post.php?action=thesis_do_css;
}
So, it doesn't work. Please help me understanding about nginx rules. Thanks.
Beny
try_files is final. You cannot put anything after it and expect it to be evaluated. Think of try files as an if-then-else statement, where the last part is always the else. Since there are probably a lot more rules involved, you are best off consulting the WordPress codex.
If you need just to rewrite that one css.css file to wp-admin/admin-post.php?action=thesis_do_css then try this:
if ($request_filename ~ wp-content/thesis/skins/classic-r/css.css ) {
rewrite ^ http://mydomain.com/wp-admin/admin-post.php?action=thesis_do_css? permanent;
}
That should be within your server{ block. Make sure to change mydomain.com to your actual domain, of course.
I hope that helps.

Resources