Как выпустить относительный URL-адрес перенаправления из nginx?

Как можно перенаправить перенаправление в nginx для ответа на определенный URL с относительным перенаправлением на определенный путь?

документация nginx предполагает, что это режим по умолчанию для nginx, но на самом деле, если перенаправление места на начало с помощью /nginx отвечая абсолютным URL-адресом в поле "Местоположение".

Для локальной конфигурации сервера, содержащей местоположения:

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

В ответ на запрос в /a:

Location: some/path

и для /b это:

Location: http://127.0.0.1/qwerty

однако мы хотели бы, чтобы /b отвечал:

Location: /qwerty

Причина, по которой мы хотели бы использовать относительные перенаправления, заключается в том, что мы хотели бы получить доступ к nginx из разных доменов и прокси, например. в явном виде в dev или через ssl-оканчивающийся балансировщик нагрузки, и скорее сохранит все просто, освободив nginx от необходимости понимать этот контекст.

FYI эти примеры были протестированы против версий nginx 1.4.6 и 1.9.6 с использованием curl, например:

curl --head http://127.0.0.1/b

Ответ 1

Фильтр заголовка nginx всегда вставляет <scheme>://<host>, если return uri начинается с /.
(для справки см. функции ngx_http_script_return_code() и ngx_http_header_filter() в источнике nginx)


Итак, если клиент (например, Google Chrome) может принять Location: /qwerty, вы можете использовать следующую конфигурацию:

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

Другое решение может генерировать Location: /qwerty точно через директиву lua-nginx-module и add_header :

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

Как работает эта странная конфигурация?

  • используйте ngx.exit для выхода с кодом состояния с 301, он не создает заголовок "Location" (директива return всегда создает заголовок "Location", даже пустое значение заголовка)
  • используйте add_header для добавления заголовка Location: /qwerty, он не вставляет <scheme>://<host>

Ответ 2

Существует директива nginx absolute_redirect, доступная в версии nginx 1.11.8, которая включена по умолчанию. Если отключено, перенаправления, выпущенные nginx, будут относительными. Эта проблема немного старше, но может быть полезной для всех, кто нажал на нее в Google.

 absolute_redirect off;