I m using nginx webserver.
I want to change the url before it hits the server from
https://www.example.com/abc/contact-us
to
https://www.example.com/#/contact-us
Thanks in advance.
For a single URI redirection, an exact match location and return statement may be most efficient:
location = /abc/contact-us {
return 301 /#/contact-us;
}
To redirect all URIs beginning with /abc use a rewrite directive:
location ^~ /abc/ {
rewrite ^/abc(.*)$ /#$1 permanent;
}
The location block is largely redundant, but means nginx only looks at the regular expression when it needs to. See this document for more.
Related
I have a URL like so: https://example.org/v2?product=lifesum and I need to rewrite it to be: https://example.org?version=v2&product=lifesum. The URL may have more or less query params, so I need to keep all of those. Also, the /v2 may actually not be present, so I need to handle those cases. Here are some examples of how this should be rewritten:
https://example.org/v2?product=lifesum ->
https://example.org?version=v2&product=lifesum
https://example.org?product=lifesum ->
https://example.org?product=lifesum
https://example.org/v13/foo/bar?product=lifesum -> https://example.org/foo/bar?version=v13&product=lifesum
https://example.org/v1113 -> https://example.org?version=v1113
https://example.org -> https://example.org
Here is what I have tried so far, but it is not working:
# HTTP Server
server {
# port to listen on. Can also be set to an IP:PORT
listen 8080;
# This is my attempt to match and rewrite
location ~* (\/v\d+) {
rewrite (\/v\d+) /?api_version=$1 break;
}
location = / {
# I have also tried this rewrite but iit is not working either
rewrite (\/v\d+) /?api_version=$1 break;
try_files $uri $uri/ /index.html;
}
}
NOTE: This is a Single Page Application, if that helps.
To meet all of your requirements, you will need to capture that part of the URI which follows the version string.
For example:
rewrite ^/(v\d+)(?:/(.*))?$ /$2?version=$1 redirect;
The redirect flag causes Nginx to use an external redirect with a 302 status (see this document for details). An external redirect is necessary for the SPA to see the new URI.
The rewrite statement can be placed in the outer server block or within a location block that matches the original URI (for example: location ~* ^/v\d).
To avoid Nginx adding a port number to the redirected URI, use:
port_in_redirect off;
See this document for details.
I want to redirect certain requests to different location, but with part of the request header, example:
https://example.com/something/value ---> https://example.com/something/index.php?var=value
pseudo-code:
location ^~ /something/$value {
return 301 https://$host/something/index.php?var=$value;
}
The location only needs to match that part of the URI which is constant. If /something/index.php and /something/value is the same prefix, then you do not want to use the ^~ modifier, otherwise the PHP file will not be found. See this document for details.
Use rewrite to capture the "value" part of the URI and append it as an argument.
For example:
location /something/ {
rewrite ^/something/(.*)$ /something/index.php?var=$1 last;
}
If you want an external redirection use rewrite...permanent instead of rewrite...last. See this document for details.
Let's say I have example.com and I'd like to rewrite anything after / to root, i.e. example.com/one/two?whatever=foo should go back to example.com
I've tried the following:
location = / {
index index.html;
}
location / {
rewrite ^ / permanent;
}
But this gives me too many redirects error. I could go route using regex to specify all the allowed/disallowed characters, but that would make it too ugly/long/complex.
Why does the exact match can't tell the difference?
You use the index directive to perform an internal rewrite from / to /index.html. See this document for details.
nginx then restarts the search for a matching location, which results in a loop.
You could add an exact match for the /index.html URI, for example:
location = /index.html { }
If index.html pulls in local resources (e.g. css, js, images), you will also need to handle those URIs specially.
Using NGINX as a load balancer running on 10.1.2.15:9002, I have a need to rewrite http://10.1.2.15:9002/proxy.stream?opt=1 to http://10.1.2.15:9002/app/proxy.stream?opt=1.
Following are bits from my nginx.conf file:
http {
upstream app_cluster {
server 10.1.2.23:8080;
server 10.1.2.25:8080;
}
server {
listen 9002 default_server;
location /app/ {
proxy_pass http://app_cluster/;
}
location ~ ^/proxy.stream(.*)$ {
rewrite ^(.*)$ /app/$request_uri last;
}
}
}
By the way, I can replace the rewrite line with return 401 (for example), and I can see the 401 HTTP status returned using Chrome Developer Tools, so I know the regex is matching. I just can't get the URI rewritten properly. In fact, I only see the original request with a 406 status in Developer Tools, so I suspect something is wrong with my rewrite syntax.
Does anyone see what is wrong with this configuration?
Using $request_uri in the replacement string of a rewrite statement is problematic, as it has not been normalised and also contains the query string, which by default, rewrite will append again.
Also, your replacement string contains //, as you are appending a URI which already has a leading /.
The regular expression location is not necessary, as a prefix or exact match location will suffice and is more efficient for nginx to process. See this document for more.
For example:
location /proxy.stream {
rewrite ^ /app$uri last;
}
Make use of the matching part from the regex instead of $request_uri
rewrite ^(.*)$ /app/$1 last;
I'd like to rewrite all requests to Nginx matching http://*.examle.tld/files/* to http://$1.otherdomain.tld/files/?file=$2. I'd also like to rewrite the same request without the subdomain i.e. http://example.tld/files/* to http://otherdomain.tld/files/?file=$1
The reason for this is to use production files from local development without having to sync folders.
This is what I've got so far, however without success:
location / {
...
rewrite ^http://(\w+)\.(.*)/files/(.*) http://$1.otherdomain.tld/inc/reader.php?file=$3;
rewrite ^.*/files/(.*) http://$1.otherdomain.tld/inc/reader.php?file=$1;
...
}
Thank you for any assistance.
You cannot use the server name as part of the rewrite directive's regex. If you have a server block with a wild card server_name as described here, you can use a named capture for use later within the block.
For example:
server {
server_name ~^(?<sub>\w+\.)?example\.tld$;
location /files/ {
rewrite ^/files(.*)$ http://${sub}otherdomain.tld/files/?file=$1 permanent;
}
}
See this document for details.