nginx rewrite url without changing browser address
Your rewrite logic is fine since its working correctly in normal schenerio. Browser URL is changing for 302 redirect because rewrite
directive just changes the request URI, not the response of request.
A typical 302 reponse looks like this:
HTTP/1.1 302 Found
Location: http://overrideurlrewriting.com
Location
header in 302 response forces the browser to follow mentioned url.
Possible solution is to modify Location
header from the proxied response (in case of 302 redirect) using proxy_redirect
directive
Helpful links:
https://stackoverflow.com/a/26025618/2073920
http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_redirect
Related videos on Youtube
Syed Osama Maruf
Updated on September 18, 2022Comments
-
Syed Osama Maruf over 1 year
I want to change the url of a request but the browser address should not change. To achieve this I have tried the below configuration:
location /my-website { proxy_pass http://tomcat/my-website; } location =/my-website { rewrite /my-website$(.*) $1/my-website/mypage/index.html last; }
Although doing this the request does get the correct address but the address bar of the browser also changes.
Also tried;
location /my-website { proxy_pass http://tomcat; rewrite /my-website$(.*) $1/my-website/page/index.html break; }
Any suggestion(s) on improving this configuration?
Expected Output
address bar: protocol://localhost/my-website
actual: protocol://localhost/my-website/page
Current Output
address bar: protocol://localhost/my-website/page
actual: protocol://localhost/my-website/page
Things tried :
- https://www.claudiokuenzler.com/blog/436/nginx-rewrite-url-examples-with-without-redirect-address#.W3_a6M4zaUk
- https://stackoverflow.com/questions/15322826/nginx-rewrite-without-change-url
Edit
The above issue is being faced on a 302 redirect. For other cases the url is changed without changing the browser address. I am handling the latter case using the below config:
location /my-website { proxy_pass http://tomcat; rewrite ^(.*)my-website/src(.*)$ $1my-website/page/src$2 break; }
i.e. that location is followed by /src and it works.
In the 302 case the location is just my-website/ and the above tried things fail.
My file config:
events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"' '"$upstream_http_location"'; rewrite_log on; #log_format graylog2_format '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" "$http_x_forwarded_for" <msec=$msec|connection=$connection|connection_requests=$connection_requests|millis=$request_time>'; error_log logs/error.log warn; sendfile on; keepalive_timeout 65; map $http_user_agent $ua_redirect { default 'abc'; } upstream docker-mysite { server localhost:9012; } proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Host $server_name; proxy_set_header X-Forwarded-Proto $scheme; proxy_read_timeout 900; client_max_body_size 0; server { listen 80; access_log logs/host.access.log main; #below config works location /mysite { proxy_pass http://docker-mysite; rewrite ^(.*)mysite/src(.*)$ $1mysite/$ua_redirect/src$2 break; } #below config works but modifies the browser url hence the issue location = /mysite { proxy_pass http://docker-mysite; rewrite /mysite(.*)$ /mysite/$ua_redirect$1 break; } } }
Logs
127.0.0.1 - - [03/Sep/2018:11:46:07 +0500] "GET /mysite/login?code=token HTTP/1.1" 302 0 "http://localhost/loginapp/web/index.html" "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36" "-"http://localhost/mysite/abc 127.0.0.1 - - [03/Sep/2018:11:46:07 +0500] "GET /mysite/abc HTTP/1.1" 404 0 "http://localhost/loginapp/web/index.html" "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36" "-"-
-
Rhys over 5 yearsTo extend on this answer: Your rewrite of
rewrite /my-website$(.*)
is basically saying that the URL ends at/my-website
as $ is the symbol for end-of-line in PCRE. Nginx uses the PCRE library during compilation. A good place to test out your regex is at regex101.com -
Syed Osama Maruf over 5 yearsjust tried your solution. the url is correctly re written however the browser address is also changed. i don't know if it will help but the re write is to happen on a 302 server redirect. For other cases the following config works fine proxy_pass docker-iam; rewrite ^(.*)iam/src(.*)$ $1iam/$ua_redirect/src$2 break;
-
Syed Osama Maruf over 5 yearsi will add this to the question as well