Как выпустить относительный 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;