Nginx Exclude a query string url from being redirected - redirect

I am currently redirecting my root domain to a subfolder. However I want to exclude a query string url which is used for an ajax call (www.example.com/?act=12). I am however unsure of how to do this in nginx.
This is my current nginx config file
server {
listen 80;
server_name example.com;
return 301 http://www.example.com$request_uri;
}
server {
listen 80;
server_name www.example.com;
root /var/www/example.com/public;
index index.php index.html;
location = / {
return 301 http://www.example.com/it/;
}
location / {
proxy_pass http://localhost:8080;
include /etc/nginx/proxy_params;
}
location ~* \.(js|css|jpg|jpeg|gif|png|svg|ico|pdf|html|htm)$ {
expires 30d;
}
location ~ /\.ht {
deny all;
}
}
Any help will be appreciated.

That can be achieved by using the evil if block.
The query string arguments are presented as variables with a $arg_ prefix. If you just need to test that act is set, try this:
location = / {
if ($arg_act) {
rewrite ^ /my/ajax/call last;
}
return 301 http://www.example.com/it/;
}
If you need to test for a specific value of $arg_act use the = operator.
See this document for details.

Related

Conditionally make Nginx redirects to index.html

how to redirect to index.html for all the url except when the url has one particular QueryString?
For example:
Redirect all other url with Query strings to index.html except when it has ngsw-cache-bust
example.com/ngsw.json?ngsw-cache-bust=0.24039143891136616
i tried the following code
server {
index index.html;
root /dist;
listen 80;
location / {
try_files $uri$args $uri$args/ /index.html;
}
}
what am i missing?
Perhaps you could try something like this
server {
index index.html;
root /dist;
listen 80;
location / {
if($arg_ngsw-cache-bust == "") {
rewrite ^(.*)$ /index.html last;
}
}
}

Add slash to redirect if URL is not ending with slash in Nginx

I wanted to add a slash to a redirect URL because the target (Wordpress) also redirects if the url does not end with a slash. This would result in two redirects.
My current config doesn't seem to work
server {
listen 80;
server_name old.domain.com;
location ~ ^(.*)[/]$ {
return 302 https://new.domain.com/$request_uri;
}
location ~ ^(.*)[^/]$ {
return 302 https://new.domain.com/$request_uri/;
}
}
Try to put url with '/' before without '/', might it matching with first without slash and redirecting it
Try this
server {
listen 80;
server_name old.domain.com;
location ~ ^(.*)[/]$ {
return 302 https://new.domain.com/$request_uri/;
}
location ~ ^(.*)[^/]$ {
return 302 https://new.domain.com/$request_uri;
}

nginx conditional redirects rules

I have such a task:
http://www.realtyadvisorselite.com/homes-for-sale/skokie
to redirect permanently to
http://www.realtyadvisorselite.com/residential/homes-for-sale/skokie
another words add "residential" subfolder if it is missing from url
I have such server blocks in nginx.conf
server {
listen 80;
server_name realtyadvisorselite.com;
return 301 http://www.realtyadvisorselite.com$request_uri;
}
server {
listen 80;
server_name www.realtyadvisorselite.com;
location / {
proxy_pass http://repar;
}
}
Sorry, seems like a simple task but I cannot understand nginx regexp approach... Thank you!
You question implies that it is a single URL that requires redirection. So a simple option is to use an exact match location and a return statement:
location = /homes-for-sale/skokie {
return 301 /residential/homes-for-sale/skokie;
}
If you wanted all URIs that begin with /homes-for-sale to be prefixed with /residential, you could use a prefix location and a return statement:
location ^~ /homes-for-sale/ {
return 301 /residential$request_uri;
}
See this document for more.

How to redirect a specific path to the same path without www in nginx

I've encountered an issue during server configuration: I require a 301 redirect from http://www.example.com to http://example.com just for one specific url alias - like /partners.
the expected output- http:// www.example.com/partners/stuff -> http:// example.com/partners/stuff.
I've tried adding the following code to the vhosts already:
server {
server_name http://www.example.com/partners;
return 301 $scheme://example.com/partners;
}
but vhosts gives me an error telling me this code isn't valid.
What's the correct way of implementing such rewrite?
server_name is for domain only. I can suggest you 2 solutions.
Copy configs between servers. This is the best solution recommended by nginx's author.
server {
server_name example.com;
include example.com.conf;
}
server {
server_name www.example.com;
include example.com.conf;
location /partners/ {
return 301 $scheme://example.com$request_uri;
}
}
Or using if. Bad solution due performance
server {
server_name .example.com;
...
location /partners/ {
if ($host = "www.example.com") {
return 301 $scheme://example.com$request_uri;
}
}
}
http://wiki.nginx.org/IfIsEvil
http://wiki.nginx.org/Pitfalls#Server_Name

domain to www.domain redirection

I have an nginx server behind varnish and I am trying to do a domain to www.domain redirection .
I tried using these rules on nginx
rewrite ^(.*) http://www.domain.com$1 permanent;
return 301 ^ $scheme://www.domain.com$request_uri;
return 301 http://www.domain.com$request_uri;
But I get an error in chrome as website running into a redirection loop.
As the about solution did not work I tried an alternative writing rules in varnish
sub vcl_recv {
// ...
if ( req.http.host == "domain.com" ) {
error 750 "http://www." + req.http.host + req.url;
}
// ...
}
sub vcl_error {
// ...
if (obj.status == 750) {
set obj.http.Location = obj.response;
# Set HTTP 301 for permanent redirect
set obj.status = 301;
return(deliver);
}
// ...
}
I am using varnish 4 and I get an error that varnish can't compile the code.
Message from VCC-compiler:
Expected an action, 'if', '{' or '}'
('input' Line 29 Pos 3)
error 750 regsub(req.http.host, "^www\.(.*)", "http://\1");
--#####------------------------------------------------------------------------------------------------------------------------
Could some one please help me in fixing this?
My server block is a follows:
server {
listen 127.0.0.1:8080;
root /home/webadmin/html/livesite;
index index.php index.html index.htm;
server_name www.domain.com;
# rewrite ^(.*) http://www.domain.com$1 permanent;
# return 301 ^ $scheme://www.domain.com$request_uri;
# return 301 http://www.domain.com$request_uri;
location / {
try_files $uri $uri/ /index.php?q=$uri&$args;
}
error_page 404 403 /error/eror.html;
location = /error/error.html {
root /home/webadmin/html/livesite;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /home/webadmin/html/livesite;
}
#pass the PHP scripts to FastCGI server listening on 127.0.0.1:9$
location ~ \.php$ {
#fastcgi_pass 127.0.0.1:9000;
# With php5-fpm:
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
}
}
This would be a correct way to do it while preserving the uri and the query string,
return 301 $scheme://www.domain.com$request_uri$is_args$query_string;
The problem isn't in this part, the problem is where you are redirecting to, probably redirecting to another locations that also does another redirect, I would guess you don't have another server block to handle the www server separately, so you keep redirecting to the same place over and over, wouldn't know for sure till you post the rest of the config.
EDIT:
The issue like I said is that you are redirecting the www to the www server, to avoid that you should create a new server that isn't with the www to do the redirection
server { # the redirecting server
listen 8080; # according to your config
server_name domain.com; #without www
return 301 $scheme://www.domain.com$request_uri$is_args$query_string;
}
server { # the actual serving server
listen 8080;
server_name www.domain.com;
# the rest of your actual settings
}
Use varnish for this instead, and skip the apache rewrites.
This example is to always redirect to https, but the semantics is the same..
In sub vcl_recv:
if ( req.http.host ~ "^(?i)domain.com" )
{
set req.http.X-Redir-Url = "https://domain.com" + req.url;
error 750 req.http.x-Redir-Url;
}
and then in sub vcl_error:
if (obj.status == 750) {
set obj.http.Location = obj.response;
set obj.status = 302;
return (deliver);
}