I have a site with two RESTful URL schemes:
foo.com/model/id and
foo.com/model/id/action
The actual pages served by these URLs are in the form of
$model.php?id=$id and
$model_$action.php?id=$id respectively.
I have a single regular expression that will match both cases ^(\w+)s/([A-z0-9]+)(?:/(\w+))?/?$ and I'd like to use a single Nginx rule to rewrite for both types of URLs, but I'm not sure how to do this. In pseudocode I imagine the rule would look something like this
rewrite ^(\w+)s/([A-z0-9]+)(?:/(\w+))?/?$ /(($3) ? $1_$3.php?$id=$2 : $1.php?$id=2)
This isn't valid syntax (so far as I know), but can something like this be done in Nginx?
Rewrite the possible urls in turn starting with the longest to the shortest to that overlapping matching strings, "/model/id" in this case, would be matched in the longer url string first.
location / {
# For "/model/id/action" to "$model_$action.php?id=$id"
rewrite ^/(.+)/(.+)/(.+)(/?)$ $1_$3.php?id=$2 last;
# For "/model/id" to "$model.php?id=$id"
rewrite ^/(.+)/(.+)(/?)$ $1.php?id=$2 last;
}
location ~ .+\.php$ {
# Handle PHP
}
The "(/?)" is just in case the urls sometimes come with an ending slash. If they never do, it can be removed. In this case, it will probably be best to specifically always add a closing slash and have "(/?)" as "/".
Related
I'd like a single nginx rewrite rule, hopefully in one line of code because I have to make a bunch of these, that can match and redirect either of these:
/short_url
/short_url?utm_source=email
without matching and redirecting:
/short_url/page.html
/short_url/page.html?utm_source=email
And if the query string exists, I want to pass it on.
I was hoping this would work, but no:
rewrite (?i)^/short_url /new_short_url$is_args$args permanent;
What's the secret sauce?
URL params are always passed with rewrite, no need to explicitly declare them in new URL.
## /short_url
## /short_url?utm_source=email
rewrite ^/short_url(\?utm_source=email)?$ /new_uri
I am trying to use Nginx rewrite static file path to strip the hash added for cache busting. The hash is always 10-symbol long. For example,
/min/3rd.party.min.1234567899.js has to become /min/3rd.party.min.js
I have tried this, but it doesn't work (fails at configtest) and also looks way to complicated.
location /min/ {
root /opt/app/public;
rewrite ^.*(?<=(.))[a-z0-9]{10}[.](?=(js|css))[js|css]$ $1$3;
}
I have no idea how you arrived at your regular expression pattern, but the following seems to work:
rewrite "^(.*)\.\w{10}\.(js|css)$" $1.$2 break;
Any pattern that contains a brace, must be placed within quotes. Use the break suffix to process the rewritten URI within the same location. See this document for details, and this useful resource on regular expressions.
I want nginx to ignore the first 4 characters of a URL. For example, I want /1234/test.html to be served by the file /test.html.
How can I do that with nginx?
This can be achieved with a rewrite, probably inside the server block.
The regular expression needs to be pretty specific to avoid a rewrite loop, so careful consideration of all URIs is necessary.
If the four character prefix is always digits, this may work for you:
rewrite "^/\d{4}/(.*)$" /$1 last;
Notice the "s around the regex because of the presence of {}s.
I want to rewrite all requests after "whois" keyword in url to whois.php in nginx but can't find suitable rules.
e.g. rewrite domain.com/whois.php/TEST.COM to whois.php?domain=TEST.COM.
There are a number of options available to you. One solution is:
location ~* ^/whois.php/ {
rewrite ^(/whois.php)/(.*)$ $1?domain=$2 last;
}
Place the location block above other regex locations that might match, as regex locations are executed on the basis of the first one that matches.
See this and this for more.
I conisder moving to Nginx but I want you to ask if is possible to rewrite urls into that schema, and if you could help me a bit:
A url like http://example.com/username into profile.php?u=username. But then, will I have problems in accessing other pages like e.g. home.php
A url like http://example.php/questions/102039/that-question into questions.php?quid=102039
Thank you very much!
Yes, it is possible to rewrite URLs with Nginx.
Your first example can be handled easily by wrapping the rewrite with a block which checks if a file (home.php in your example) exists; if it doesn't, then it tries the redirect into the profile.php request. (See the try_files syntax for this.)
Your second example is just as simple:
Rewrite ^/questions/(\d+) /questions.php?quid=$1
(Because the matching expression is not anchored at the end, it should accept any string after the digits, but I haven't checked that so I'd recommend you test it.)