Rewrite Nginx URLs with Parameters (After a Question Mark) - nginx

I have URLS in this format:
/wiki/index.php?title=Widget
/wiki/index.php?title=Blue
/wiki/index.php?title=Red
/wiki/index.php?title=Etc
I want to be able to match any URL that has the pattern "/wiki/index.php?title=" or even just "/wiki/index.php" (but so it will pick up the above URLs with the "?") and then redirect them to simply /wiki/ (all pages that match the above pattern go to the single url /wiki/)
I used to have a Mediawiki install on the /wiki/ directory with a lot of pages in the format above. However now I am running a Wordpress install and it is using the /wiki/ directory. I don't need each rewritten URL to go to a different URL (I know that is difficult as my source URLs have parameters) but right now they all 404 and so I just want to direct to them /wiki/ at least.

Simple URL rewriting
The easiest case (rewrite all /wiki/index.php requests with any arguments) can be done by this config (inside your server block):
location = /wiki/index.php {
rewrite .* /wiki/?;
}
The '?' sign at the end of second rewrite parameter is a trick to completely remove any request arguments. Without it, request /wiki/index.php?title=Widget will be rewrited to /wiki/?title=Widget.
Rewriting only requests matching /wiki/index.php?title=... is a more complex, I don't know how to do it without if construction:
location = /wiki/index.php {
if ($request_uri ~ ^/wiki/index\.php\?title=) {
rewrite .* /wiki/?;
}
}
If you want to generate HTTP 301 or 302 redirect instead of simple URL rewriting, you can use redirect (for 301 temporary redirect) or permanent (for 302 permanent redirect) flag at the end of rewrite directive parameters (see documentation).
Rewriting URLs to individual pages
This task is not as difficult as it seems. For redirecting /wiki/index.php?title=Widget to /wiki/Widget, /wiki/index.php?title=Blue to /wiki/Blue etc. we can make use of map directive:
map $request_uri $uri_suffix {
~^/wiki/index\.php\?title=([^&]*) $1;
}
server {
...
location = /wiki/index.php {
rewrite .* /wiki/$uri_suffix?;
}
...
}
Please note that map directive must be declared outside your server configuration block!

Related

Rewrite Nginx Url only on specific path

So I have a main path https://app.example.com and I want it to keep it that, way but on all https://app.expample.com/p/* paths I want it to be rewritten to a short version of the url like. How can I achieve this?
I tried
location = /p/(.*)$ {
rewrite ^ https://example.com/p/$request_uri permanent; and also return 301 https://example.com/p/$request_uri;
}
but this resulted in too many http redirects and an error

Remove part url use nginx [duplicate]

I have a web server which accepts https://www.example.com/API/ooo/xxx, https://www.example.com/API/aaa/bbb, and https://www.example.com/API/xxx/yyy ... etc.
Now we want to redirect the above quests to https://www.example.com/ooo/xxx, https://www.example.com/aaa/bbb, and https://www.example.com/xxx/yyy ... etc.
I've tried using rewrite key word in nginx:
location /API/ {
rewrite ^/API(.*)$ https://$host$1 redirect;
}
This works for GET requests. But it turns POST requests to GET requests. This is something I don't want.
How can I preserve the http method while redirecting /API/* to /*?
This post says that I can use 307 redirect. But rewrite doesn't seem to support 307 redirect. And I can't figure out how to use $1 regular expression property in return.
Use a return statement. You can use a regular expression location block to capture the part of the URI to return.
For example:
location ~ ^/API(/.*)$ {
return 307 $1$is_args$args;
}
Note that with the regular expression location directive, its order within the configuration is significant, so you may need to move it. See this document for details.

nginx - Rewrite URL Parameter to Path

So we ran into an SEO issue with a WPML after changing from using URL parameters to specify the site language to using the path. The web server is running nginx.
Before:
example.com/?lang=fr
example.com/example-path/?lang=fr
After:
example.com/fr/
example.com/fr/example-path/
So what I'm trying to do is redirect any URL following the old URL format, including the root / to the new format. This process should strip all URI parameters in the URL and replace it with the corresponding path.
I reached out to the guys over at WPML and they don't know how to do it.
I've tried two different ways:
location = / {
if ($args ~ "^lang=(fr)") {
set $key1 $1;
rewrite ^.*$ /fr last;
}
}
As well as:
rewrite ^/.*\?lang\=fr$ /index.php? permanent;
But unfortunately from what I can tell, neither of these seem to do anything. I'm really familiar with regex but for some reason I'm having a hard time with these nginx rewrites.
I was surprised that there are very few examples in the nginx docs and on google about rewriting URL parameters. Any ideas on how this could be done?
Thanks!

NGINX Subdirectory Redirect is not working

TLDR: subdirectory/cool redirects to newdirectory/cool. subdirectory?cool incorrectly redirects to newdirectory without the parameter.
The Prob:
I'm attempting to redirect a subdirectory to a new directory while preserving the original URL parameters via NGINX location using the regex ~* ^(?:((\/m\b)(?!-)(\/)?))(?<requestedPath>.*)?$
The paths such as /subdirectory/cool successfully redirect to /newdir/cool. However, paths like /subdirectory?cool and /subdirectory/?cool are redirecting to /newdir without preserving the URL parameters.
The redirect should work as follows:
/subdirectory -> /newdir
(Many of the suggestions I've seen posted here for subdirectrory redirects assume a trailing slas or do not take into account that their regex for /m also impacts /media)
/subdirectory/ -> /newdir/
/subdirectory/test -> /newdir/test
/subdirectory/?apple -> /newdir/?apple
/subdirectory?apple -> /newdir?apple
The test is successful here: Successful Test
The code that is failing:
location ~* ^(?:((\/subdirectory\b)(?!-)(\/)?))(?<requestedPath>.*)?$ {
return 301 /newdir/$requestedPath;
}
Additionally, I have also tried using rewrite instead of location to no avail.
Apparently, with location, one has to us $is_args.
This did the trick: return 301 /newdir/$requestedPath$is_args$args;
End result:
location ~* ^(?:((\/subdirectory\b)(?!-)(\/)?))(?<requestedPath>.*)?$ {
return 301 /newdir/$requestedPath$is_args$args;
}

Nginx: redirect regardless of the url structure

I recently moved a subdomain to my main domain but I also changed the url structure.
Previously I had pages like http://sub.domain.com/companies/my-company-id/year/2012/charts
When moving to the main domain, I removed all the complicated urls to juts get:
http://www.domain.com/companies/my-company
I currently have the following rule:
rewrite ^/companies/(.*)$ http://www.domain.com/companies/$1 permanent; but when someone go on a page like http://sub.domain.com/companies/my-company/2012/charts they get redirect to http://www,.domain.com/companies/my-company/2012/charts and get a 404.
I like to force a redirection to http://www,.domain.com/companies/my-company-id regardless of what's after the my-company-id
Currently the parameter $1 is having the entire URI after /companies, so you are getting redirected to the original path. You should only extract the company-id in $1.
Use this:
rewrite ^/companies/(.*)/(.*)$ http://www.domain.com/companies/$1 permanent;
Here the rest of the URI after company-id will be available in the parameter $2, which is not needed in the rewrite condition.

Resources