Removing only a specific URL parameter in Nginx with rewrite - nginx

I'm trying to make Nginx remove only a specific parameter from the requested URL. Let's say that the parameter name is par2. Here are the examples of requested URLs:
www.example.com/page?par1=a&par2=b
www.example.com/page?par2=b
Those pages should redirect to:
www.example.com/page?par1=a
www.example.com/page
Here is what I have in conf file at the moment:
location / {
...
if ($args ~* "par2") {
rewrite ^(.*)$ $request_uri permanent;
}
}
This partly works - it does remove par2 parameter, but it removes all of the other parameters as well and redirects to:
www.example.com/page
www.example.com/page
How to make it remove only a specific parameter (par2 in this case)?
EDIT:
As far as I know, it's recommended to use if only if it's followed by rewrite, so I'd prefer such a solution.

This should work for your use case when parameter can be anywhere
location /page {
if ($request_uri ~ ^(/page)(.par2=[0-9a-zA-Z]&?)$){
return 302 $1;
}
if ($request_uri ~ ^(/page\?.+)(.par2=[0-9a-zA-Z])(.*)$){
return 302 $1$3;
}
if ($request_uri ~ ^(/page\?)(par2=[0-9a-zA-Z]&?)(.+)$){
return 302 $1$3;
}
}

Related

how to create an nginx rewrite to add / to url

I'm trying to create an nginx rewrite that will rewrite /pagename to /pagename/
I've tried using:
location ~ "^/test$" {
rewrite /test /test/ break;
}
but that doesn't seem to work...
any help would be appreciated.
The first parameter of a rewrite statement is a regular expression, and the flag you should use is probably permanent (see this document for details), for example:
location ~ "^/test$" {
rewrite ^(/test)$ $1/ permanent;
}
But you do not need to match the regular expression twice, once in the location and again in the rewrite, so a return would be more efficient, for example:
location ~ "^(/test)$" {
return 301 $1/$is_args$args;
}
Also, the location matches a single URI, to the = operator would be better than a regular expression (see this document for details). So the preferred solution is:
location = /test {
return 301 $uri/$is_args$args;
}
I ended up using return:
return 301 /test/;

convert url get parameters to url segment in nginx

I have this URL https://example.com/user?param1=value1&param2=value2&param3=value3
and have it to go to https://example.com/user/value1/value2/value3 on the Nginx server.
Just FYI it is WordPress site and I have added the following rule in the Nginx config file.
location ~ /user/ {
if ($args ~* "^param1=(\d+)&param3=(\d+)&param3=(\d+)") {
set $param1 $1;
set $param2 $1;
set $param3 $1;
set $args '';
rewrite ^.*$ /user/$param1/$param2/$param3 permanent;
}
}
Your solution has two errors, 1) the location does not match /user, and 2) the rewrite is also appending the original arguments.
This could be fixed by using an exact match location and a trailing ? on the rewrite. For example:
location = /user {
...
rewrite ^ /user/$param1/$param2/$param3? permanent;
}
However, the map statement is a cleaner and extensible solution, for example:
map $request_uri $redirect {
default 0;
~*^/user?param1=(?<p1>\d+)&param2=(?<p2>\d+)&param3=(?<p3>\d+)$ /user/$p1/$p2/$p3;
}
server {
...
if ($redirect) { return 301 $redirect; }
...
}
See this document for details.

nginx rewrite rule with query parameter

My URL looks like:
localhost/video-detail?videoID=T0r-uCXvDzQ
I want to serve a page with name: T0r-uCXvDzQ.html (videoID.html) which is present in server's file system.
I am trying to write the rewrite rule as follows:-
location / {
rewrite ^/video-detail?videoID=(.*) /$1.html;
}
Also tried:
location / {
rewrite ^/video-detail?videoID=(.*) /$arg_videoID.html;
}
But they are giving 404 error.
How can I use the query parameters in the output rewrite rule.
The following worked for me:-
if ($args ~* "videoID=(.*)") {
set $key1 $1;
rewrite ^(/video-detail)$ /$key1.html;
}

Nginx: filter characters from URI

I try to redirect some URLS with Nginx but having problems to combine filtering and stripping.
Redirect:
location ~* "^/7_skin/skin_archi/skin_control/text_box$" {
if ($request_uri ~* "([^/]*$)" ) {
set $last_path_component $1;
}
return 301 https://www.domain.com/wiki/display/$last_path_component;
}
this works fine and filters every path but last. Now I would like to strip characters (- and _) from $last_path_component but that doesn't seem to work.
I tried something like: rewrite ^(.*)[-_](.*)$ $1$2 permanent;
which worked, but not in conjunction with first filter as the whole path is given out.

If Is Evil - Nginx

I'm using Nginx 1.6.2. I read that if () is evil and it's not good using it so I need a bit help, because I can't do what I want without using if(). I will post the rules I have with if and would ask if somebody could help me and tell me how to not use if () and use something else and get the same result.
# REDIRECT NON-WWW TO WWW.
if ($http_host != "www.site.eu") {
rewrite ^ http://www.site.eu$request_uri permanent;
}
# REMOVE INDEX FILES FROM URL FOR SEO PURPOSE.
if ($request_uri ~ "/index.php") {
rewrite ^ /$1 permanent;
}
# REMOVE ANY MULTIPLE SLASHES IN THE URL.
if ($request_uri ~* "\/\/") {
rewrite ^/(.*) $scheme://$host/$1 permanent;
}
First rule should be replaced with separate server blocks
server {
listen 80 default_server;
return 301 http://www.example.com$request_uri;
}
server {
listen 80;
server_name www.example.com;
# normal config
}
Other ifs usually are not necessary. Just don't generate links with index.php and you will not need to strip it.
In the official wiki introduction it says that there are some cases which are ok. Have a look at this quote:
The only 100% safe things which may be done inside if in location
context are:
return ...; rewrite ... last;
At the end of the introduction there is an example which also features a rewrite command. So your code looks ok, too.
EDIT: You should also have a look at how the if works.
You can replace this block
# REMOVE INDEX FILES FROM URL FOR SEO PURPOSE.
if ($request_uri ~ "/index.php") {
rewrite ^ /$1 permanent;
}
with this
location ~ ^/index.php/(.*[^/])$ { return 301 $scheme://$host/$1/$is_args$args; }
location ~ ^/index.php/(.*)/$ { return 301 $scheme://$host/$1/$is_args$args; }
I also don't think you need to worry about the last rule for double // because nginx by default automatically takes care of that before it even gets to the point of matching location blocks

Resources