Redirecting and rewriting in NGINX - redirect

I'm trying to create a simple "Hello World"-like API and for that I need a rule to redirect/rewrite the URL to my API.
Let's say my file is called index.php, so whenever I make a GET to index.php I get a list of items.
The first thing I want to do is to redirect the URL mydomain.com/index.php to mydomain.com/api.
And second, when mydomain.com/api is accessed, I'd like the server to trigger the index.php file without rewriting the URL.
My current code looks like this:
location /api {
rewrite ^ $scheme://$host/index.php permanent;
}
location /index.php{
return 302 www.mydomain.com/api;
}
but it's not working as expected. Why and how can I fix it?

You need two rules for what you're trying to achieve.
The first one, the one that will receive requests and "translate" them to your under-the-hood script, should look like this:
rewrite ^/api\?(.+)$ /index.php?$1 last;
As for the second one, the one that should redirect all your users to the "beautiful" URL:
rewrite ^/index.php\?(.*)$ /api?$1 permanent;
Note that this second rule should be outside any location block and before any of those, as you're willing to redirect the user before anything else.
Cheers

# you don't need a rewrite. Use location with the "=" or exact match
location = /api {
alias /path/to/root;
index index.php;
}
location /index.php {
return 302 www.mydomain.com/api;
}
Hope it helps
Here is the second version of my answer using one redirect and an alias:
location /api {
alias /path/to/root;
index index.php;
}
# replace index.php with api
location /index.php {
rewrite (index\.php)(.*)$ /api$2 permanent;
}
My first solution did not forwarded the args. Reading #alexandernst solution gave a better idea of the problem.

Related

how to create website redirect with a # in the link

I need to create a redirect in the Serverblock on my nginx Server.
I want to use the same code which is already working for other redirects:
http://www.domain.com/text
location /text {
rewrite ^/.* http://www.domain.com/target permanent;
}
this works fine!
But this code is not working with a specific link
http://www.domain.com/#text/text
location /#text/text {
rewrite ^/.* http://www.domain.com/target permanent;
}
I believe it is because of the # sign but my problem is I need the exact URL name with the # sign. Is there a way to uncomment a # sign or do I need to go a complete different way?

nginx 301 redirect with query_string variable and if

I'm new to nginx and I need to setup up a load of 301 redirects each pointing old files to the new ones, like this:
# www.domain.com/products/category/product.php?id=103
# to
# www.domain.com/products/new-category-name/new-product-name.html
To deal with the ? I have the following which seems to be working fine:
if ($args ~ "id=103") {
rewrite ^ /products/new-category-name/new-product-name.html? permanent;
}
How does this look? I'm aware that if is mostly a bad idea in nginx but I don't fully understand why. Is the above rule okay? it seems to work fine. Lastly, I have around 100 of these urls to redirect. Will it be okay to just duplicate this rule for each url?
Thanks
UPDATE
The mapping looks to be a great solution but I'm not sure where to place the code. I currently have the following:
location / {
try_files $uri $uri/ #modx-rewrite;
}
It's stated that any additional rules need to be placed before this location block.
I would sugguest to use the ngx_http_map_module
create a file for the urlmapping, that contains old and new urls, like
/products/category/product.php?id=103 /products/new-category-name/new-product-name.html ;
/products/category2/product.php?id=104 /products/new-category2-name/new-product104-name.html ;
that's easy to maintain. just add a new line for a new mapping and reload your nginx config.
in your nginx config create a location with a mapping like
map $request_uri $newuri {
include /path/to/your/mappingfile;
}
server {
...
location / {
if ($newuri) {
return 301 $newuri;
}
}
}

Nginx redirect all contents of a subdirectory to another subdirectory

Let say that I have a url like this:
http://www.example.com/admin/admin.php?fail=1
how can I rewrite the url to be
http://www.example.com/another/subdirectory/admin.php?fail=1
Thank you
Update: this is what I've tried so far, but it will not redirect admin.php?fail=1
location /admin/ {
rewrite ^/admin/(.*)$
/another/subdirectory/$1 redirect;
}
I rather use return 301 for redirections and use rewrite only if I want to display something like a nice url.
Please try the following
location ~ ^/admin/(.*) {
return 301 /another/subdirectory/$1 ;
}

Nginx rewrite subfolder to subfolder

I have been having issues redirecting an old subfolder entirely to a new subfolder. I need to have both /old and /old/ go to /new and /new/ respectively
I also need to have any parameters followed after /old/blah/blah2/ to /new/blah/blah2/ so just basically replacing old with new no matter whats called. The below is the closest I can get.
location /account/ {
rewrite ^/account/(.*)$ https://$server_name/portal/$1 permanent;
}
Example of an actual URL:
www.domain.com/account/index.php?loend=true&cmd=callback&module=8
needs to be
www.domain.com/portal/index.php?loend=true&cmd=callback&module=8
Thank you
Can you try rewrite ^/account/(.*)$ /portal/$1; ? No need to put it into location /account/ { ... } – Guillaume Filion Jul 24 at 19:00
Using just: rewrite ^/account/(.*)$ /portal/$1;
without specifying the location has resolved all issues
Its should work but you're missing $ sign in it.
Here is corrected a bit code
rewrite ^/account/(.*)$ https://$server_name/portal$1 redirect;
or
rewrite ^/account/(.*)$ https://$server_name/portal$1 last;
or
rewrite ^/account/(.*)$ https://$server_name/portal$1;
Than reload config of nginx
service nginx reload
here is source site.
https://www.digitalocean.com/community/questions/301-redirect-nginx
Since this seems more of a redirect than a rewrite, I would use return
location ^~ /account(.*) {
return 301 https://$server_name/portal$1$is_args$query_string;
}
The $is_args$query_string is to append any query string like you mentioned in one of the comments loend=true&cmd=callback&module=8 and also mind that if the $server_name is the same name of server_name you can replace it with $http_host and keep it dynamic.

How to set up nested subfolder to subdomain Nginx 301 redirects

I'm trying to set up Nginx redirects that will rewrite any URL from several older forum setups to a new forum. The older forums ran from subfolders, while the current forum is running from a subdomain of the same site.
So, for example, I want ANY request to site.com/ask to be redirected to the front page of forum.site.com. Since I'm dealing with 3 old forums, I tried to set up a nested redirect like this:
location ~ ^/\~([^/]+)/(.*)$ {
location ~ ^/\~ask/(.*)$ {
rewrite ^(.*)$ http://forum.site.com$1 permanent;
}
location ~ ^/\~forum/(.*)$ {
rewrite ^(.*)$ http://forum.site.com$1 permanent;
}
location ~ ^/\~qa/(.*)$ {
rewrite ^(.*)$ http://forum.site.com$1 permanent;
}
}
With the above rules, only the first one works and partially. For example, a request to site.com/ask gets redirected to forum.site.com, which is fine, but any request to, say, site.com/ask/what-is-this goes to forum.site.com/404.
Request to site.com/forum and site.com/qa do not work at all.
I'm sure there's a simpler way of doing this, but I don't want to spend several days trying to figure it out.
Your input is welcome and appreciated.
Edit:
Not getting anywhere with the above code, I reduced it to this:
location ~ ^/\~([^/]+)/(.*)$ {
location ~ ^/\~(qa|forum|ask)/(.*)$ {
rewrite ^/~(qa|forum|ask)/(.*)$ http://forum.site.com$1 permanent;
}
}
But the result is still the same. Any ideas?
Actually you want to redirect user to the main page of your forum regardless of what page he came to. Try this.
location /qa/ {
return 301 http://forum.site.com;
}
location /ask/ {
return 301 http://forum.site.com;
}
location /forum/ {
return 301 http://forum.site.com;
}