I'm breaking my head on Nginx rewrite rules while migrating from Apache to Nginx.
I had .htaccess rewrite rules that made /search/foo+bar/2&pricerange=20-50 to search.php?search=foo+bar&page=2&pricerange=20-50
and I could access all the arguments like you would expect with $_GET['search'], $_GET['page'] and $_GET['pricerange']
But now with Nginx I have issues with this appended arguments like pricerange. Whenever I visit /search/foo+bar/2&pricerange=20-50 it does not translate the pricerange argument.
And when I visit the same url without the page number the pricerange argument gets added to the search argument. But only when I'm using more than one word concatenated with +'s.
My current Nginx rewrite rules:
location / {
try_files $uri /index.php$is_args$args;
rewrite ^/search/(.*)/(.*)/$ /search?search=$1&page=$2 last;
rewrite ^/search/(.*)/(.*)/?$ /search?search=$1&page=$2 last;
rewrite ^/search/(.*)/$ /search?search=$1 last;
rewrite ^/search/(.*)/?$ /search?search=$1 last;
}
GET arguments begin after the '?'
/search/foo+bar/2&pricerange=20-50
You need to replace '&' with '?' or rewrite rule
rewrite ^/search/(.*)/([0-9]+)&pricerange=(.*)$ /search?search=$1&page=$2&pricerange=$3 last;
Related
I install the prestashop 1.7 as a multistore and write nginx rewrite rule as
location /shop-1/ {
rewrite ^/shop-1/(.*)$ /$1 last;
try_files $uri $uri/ /index.php?$args;
}
location /shop-2/ {
rewrite ^/shop-2/(.*)$ /$1 last;
try_files $uri $uri/ /index.php?$args;
}
I follow the nginx conf file from https://devdocs.prestashop.com/1.7/basics/installation/nginx/
Now the Q is Parent domain navigating correctly and showing images but multistore redirected corrected to http://example.com/{shop-1 or shop-2} but not showing the images on the multishop urls, getting nginx 404 error on multishop url but same image showing on a parent domain.
example:
http://example.com/shop-1/45-medium_default/skirt.jpg not showing the image
http://example.com/45-medium_default/skirt.jpg showing the image
To explain what happened here I need to refer to nginx request processing phases, a subject not many people actually understand correctly.
Here is a set of rewrite rules being executed at the NGX_HTTP_SERVER_REWRITE_PHASE:
rewrite ^/(\d)(-[\w-]+)?/.+\.jpg$ /img/p/$1/$1$2.jpg last;
rewrite ^/(\d)(\d)(-[\w-]+)?/.+\.jpg$ /img/p/$1/$2/$1$2$3.jpg last;
rewrite ^/(\d)(\d)(\d)(-[\w-]+)?/.+\.jpg$ /img/p/$1/$2/$3/$1$2$3$4.jpg last;
rewrite ^/(\d)(\d)(\d)(\d)(-[\w-]+)?/.+\.jpg$ /img/p/$1/$2/$3/$4/$1$2$3$4$5.jpg last;
rewrite ^/(\d)(\d)(\d)(\d)(\d)(-[\w-]+)?/.+\.jpg$ /img/p/$1/$2/$3/$4/$5/$1$2$3$4$5$6.jpg last;
rewrite ^/(\d)(\d)(\d)(\d)(\d)(\d)(-[\w-]+)?/.+\.jpg$ /img/p/$1/$2/$3/$4/$5/$6/$1$2$3$4$5$6$7.jpg last;
rewrite ^/(\d)(\d)(\d)(\d)(\d)(\d)(\d)(-[\w-]+)?/.+\.jpg$ /img/p/$1/$2/$3/$4/$5/$6/$7/$1$2$3$4$5$6$7$8.jpg last;
rewrite ^/(\d)(\d)(\d)(\d)(\d)(\d)(\d)(\d)(-[\w-]+)?/.+\.jpg$ /img/p/$1/$2/$3/$4/$5/$6/$7/$8/$1$2$3$4$5$6$7$8$9.jpg last;
rewrite ^/c/([\w.-]+)/.+\.jpg$ /img/c/$1.jpg last;
As you can see, none of them matches the /shop-1/45-medium_default/skirt.jpg request URI. So on the next turn, during the NGX_HTTP_FIND_CONFIG_PHASE your location /shop-1/ { ... } will be selected to handle the request. Next, after rewrite ^/shop-1/(.*)$ /$1 last; rule being executed, your request URI will be rewritten to /45-medium_default/skirt.jpg, and due to the used last flag on the rewrite directive the NGX_HTTP_FIND_CONFIG_PHASE will be executed again. However the NGX_HTTP_SERVER_REWRITE_PHASE won't be executed again, and a new URI won't be rewritten according to those rules. What you should do instead is to place a rewrite rule at the server level before the ruleset for rewriting image requests:
rewrite ^/(?:shop-1|shop-2)(/.*) $1;
... image URIs rewrite rules here
Note that I don't use last (or break) flag for this rule since the rewrite rules chain should not be terminated after this rewrite will be triggered. None of those two locations that you show in your question will be needed at all.
I want to rewrite internally several locations /customers/foo?bar=2 to an existing location in my nginx configuration at /blah so that it's as if the request was to /blah/customers/foo?bar=2.
location /blah {
# View in fiddler
proxy_pass http://127.0.0.1:8888/;
# Lots of config here I don't want to repeat everywhere else
}
location /customers/ {
rewrite ^/customers/(.*) /blah/customers/$1$is_args$args;
}
location /other/ {
rewrite ^/other/(.*) /blah/other/$1$is_args$args;
}
# etc...
Nginx is rewriting the URL with the querystring encoded as a path /blah/customers/foo%34bar=2.
The same thing happens with rewrite ^ /blah$request_uri;. It encodes the ? as %3F effectively garbling the URL.
If I do a client redirect rewrite ^ /blah$request_uri permanent; the URL is correct and contains the ? but I want an internal redirect inside my NGINX config.
Don't use $is_args$args, because the rewrite directive will automatically append any existing query string.
For example:
rewrite ^/customers/(.*) /blah/customers/$1 last;
Although, I would prefer:
rewrite ^(.*)$ /blah$1 last;
Or even:
rewrite ^ /blah$uri last;
I want to write all the redirections of my website pages in one location block
This is what I have done so far
location /mywebsite {
rewrite ^/mywebsite$ /index.php;
rewrite ^/mywebsite/about$ /about.php;
rewrite ^/mywebsite/services$ /services.php;
rewrite ^/mywebsite/events$ /events.php;
rewrite ^/mywebsite/events/(.*)$ /events.php?id=1 last;
}
but this does not work as intended.
I am writing a rewrite rule for nginx but keep getting loop issue
How do I write the regex to only match ?page=home but stops at ?page=m-home
This is what I have right now, but doesn't really work
if ($args ~ page=[^m\-](.+)){
set $a $1;
rewrite ^(.+)$ /cms/index.php?page=m-$a permanent;
}
Can someone help me for my nginx rewrite rule. I have the problem like this
if file not found in www.abc.com/name_dir/* it will redirect to www.abc.com/name_dir/index.php .
for example :
not found in www.abc.com/xxx/* redirect to www.abc.com/xxx/index.php
not found in www.abc.com/yyy/* redirect to www.abc.com/yyy/index.php
not found in www.abc.com/zzz/* redirect to www.abc.com/zzz/index.php
not found in www.abc.com/kk/* redirect to www.abc.com/kkk/index.php
...
the problem i have thousand of name_dir. I have nginx.conf like this
if (-f $request_filename) {
break;
}
if (-d $request_filename) {
rewrite (^.+$) $1/
break;
}
if (!-e $request_filename) {
rewrite ^/xxx/(.*)$ /xxx/index.php?$1 last;
rewrite ^.+?(/.*\.php)$ $1 last;
}
In configuration above only redirect name_dir xxx. How rewrite rule to redirect all directory ?
Thank for your help
You want to use try_files to check for the existence of files instead of if statements here (because If's are Evil in Nginx).
To to a single directory, it would be like:
location /xxx/{
try_files $uri $uri/ /xxx/index.php;
index index.php
}
What this does is try the uri as a file first. If that doesn't work, it'll try as a directory. If neither work, it'll default to index.php of /xxx/. The extra index line is to keep it from showing a blank page if you go directly to whatever.com/xxx
Using regex, we can expand this rule to work with more than one directory:
location ~* ^(/.*)/{
try_files $uri $uri/ $1/index.php?$uri&$args;
index index.php
}
This should grab the full directory structure and rout it to the appropriate index.
abc.com/yyy/nonexistant.php ==> abc.com/yyy/index.php
abc.com/yyy/zzz/nonexistant.php ==> abc.com/yyy/zzz/index.php
If you only wanted the second example to go to yyy/index.php, use this regex in the location instead:
^(/.*?)/