Suppose I want to move an /images/ directory to an images host so that what was before http://example.org/images/foo.png becomes http://images.example.org/foo.png.

If I do: location /images/ { return 301 http://images.example.org$request_uri; }, the result is a redirect to http://images.example.org/images/foo.png which isn't what I want.

An older question has an answer that suggests using a regexp location, but that seems like an overkill.

Is there really no way to refer to $request_uri with the location prefix chopped off without using regular expressions? Seems like an obvious feature to have.


I don't think we could completely eliminate regex for this use case. However, here's an alternative solution that does not use regex location, but uses regex inside location block...

location /images/ {
  rewrite "^/images/?(.*)$" "/$1";
  return 301 http://images.example.org$uri;

Please know that $uri doesn't contain $args. However, $request_uri does. In this alternative solution, we modify the $uri, using a regex, before it is processed. $request_uri can not be modified, though.

  • Thanks. I really want to retain the query string, though. :-(
    – hsivonen
    Oct 20 '13 at 13:33

To add to Pothis answer, you could simply add the permanent flag to rewrite and directly redirect without using return:

location /images/ {
  rewrite ^/images/(.*)$ $scheme://images.example.org/$1 permanent;

This will also keep the parameters with the redirect.

Or, alternatively, if more modifying of the uri is needed, you can simply append $is_args and $args behind $uri:

location /images/ {
  rewrite ^/images/(.*)$ /$1;
  [ ... more rewriting ... ]
  return 301 $scheme://images.example.org$uri$is_args$args

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.