Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to issue a relative url redirect from nginx?

Tags:

How can a redirect be configured in nginx to respond to a certain url with a relative redirect to a specific path?

The nginx documentation suggests that this is the default mode for nginx, but in reality if the location being redirected to starts with a / nginx is responding with an absolute url in the Location field.

For local server configuration containing locations:

location = /a {   return 301 some/path; } location = /b {   return 301 /qwerty; } 

the response Location to a request to /a is:

Location: some/path 

and for /b it is:

Location: http://127.0.0.1/qwerty 

however, we would like /b to respond with:

Location: /qwerty 

The reason we would like to use relative redirects is that we would like to access nginx from different domains and proxies, e.g. in clear in dev or via ssl-terminating load-balancer, and would rather keep things simple by relieving nginx of needing to understand that context.

FYI these examples were tested against nginx versions 1.4.6 and 1.9.6, using curl e.g.:

curl --head http://127.0.0.1/b 
like image 261
dan moore Avatar asked Nov 04 '15 14:11

dan moore


People also ask

What is return 301 in NGINX?

Permanent redirects such as NGINX 301 Redirect simply makes the browser forget the old address entirely and prevents it from attempting to access that address anymore. These redirects are very useful if your content has been permanently moved to a new location, like when you change domain names or servers.

How does NGINX redirection work?

Redirecting on Nginx'$scheme ' variable is used to redirect the original request (i.e., http or https) to the 301 permanent redirection in the newly formatted URL. A rewrite directive can be used to process a folder redirection to a separate sub-domain or a new domain with the below configuration.


2 Answers

nginx header filter always inserts <scheme>://<host> if return uri starts with /.
(see ngx_http_script_return_code() and ngx_http_header_filter() function in nginx source for reference)


So, if client (e.g. google chrome) can accept Location: /qwerty, you can use the following configure:

location = /b {     return 301 " /qwerty";    # insert space char before "/qwerty" } 

Another solution can generate Location: /qwerty exactly, via lua-nginx-module and add_header directive:

location = /b {     add_header Location "/qwerty";     content_by_lua 'ngx.exit(301)'; } 

How does this weird configure work?

  • use ngx.exit to exit with status code with 301, it does not create "Location" header (return directive always create "Location" header, even empty header value)
  • use add_header to add Location: /qwerty header, it does not insert <scheme>://<host>
like image 145
xiaochen Avatar answered Oct 08 '22 14:10

xiaochen


There is an nginx directive absolute_redirect available from nginx version 1.11.8, which is enabled by default. If disabled, redirects issued by nginx will be relative. This issue is a bit older, but maybe useful for all of you hitting it from google.

 absolute_redirect off; 
like image 27
Wadim Avatar answered Oct 08 '22 13:10

Wadim