Мы заметили, что при использовании внутренней обработки 301 и 302 nginx будет обслуживать небольшое тело документа с соответствующим заголовком Location: ....
Что-то вроде (в html): 301 редирект - nginx.
Как и в случае с описанным выше поведением, также отправляются заголовок типа содержимого text/html и длина содержимого.
Мы делаем много перенаправлений 302 и немного 301. По нашему мнению, такое поведение приводит к пустой трате пропускной способности.
Есть ли способ отключить это поведение?
Одна из идей, которая пришла нам в голову, состояла в том, чтобы установить error_page 301 302 в пустой текстовый файл. Мы пока не проверяли это, но я предполагаю, что даже с учетом вышеизложенного заголовки content-type и content-length (0) будут отправлены.
Итак, есть ли простой способ отправить «безтеловое» перенаправление 301/302 с помощью nginx?
решение1
Подумайте очень внимательно о том, о чем вы просите, и серьезно рассмотритене делаю этого.
Запрос на изменение 2616указывает, что тела сущностей, которые вы хотите удалить, должны присутствовать.
10.3.2 301 Перемещено навсегда
Новый постоянный URI ДОЛЖЕН быть указан полем Location в ответе. Если метод запроса не был HEAD, сущность ответа ДОЛЖНА содержать короткую гипертекстовую заметку с гиперссылкой на новый(е) URI.
и...
10.3.3 302 Найдено
Временный URI ДОЛЖЕН быть указан полем Location в ответе. Если метод запроса не был HEAD, сущность ответа ДОЛЖНА содержать короткую гипертекстовую заметку с гиперссылкой на новый(е) URI.
В этом контексте СЛЕДУЕТ определить какЗапрос на предложение 2119:
Это слово или прилагательное «РЕКОМЕНДУЕТСЯ» означает, что в определенных обстоятельствах могут существовать веские причины игнорировать определенный пункт, но перед выбором другого курса необходимо понять и тщательно взвесить все последствия.
Теперь вы можете сделать это, не нарушая RFC, но вы должны осознавать все последствия:
- Вы делаете много работы практически без какой-либо выгоды. Единственная логическая причина, которую я могу придумать, чтобы отключить тело сущности, — это экономия на расходах на пропускную способность, и действительно, это причина, которую вы упомянули, но разница настолько минимальна, что вряд ли вы вообще увидите разницу на графиках пропускной способности.
- Очень малая часть веб-клиентов не следует автоматически перенаправлениям 3xx. Эта часть была намного больше, когда RFC был написан, поэтому он там изначально, но все еще есть древние чудовища, скрывающиеся в тенях темных спален и кладовок центров обработки данных, и иногда они выходят, чтобы поиграть. Тот, который вы, скорее всего, увидите
curl
, это , который все еще широко используется.
Эта рекомендация была несколько смягченаRFC7231, который просто говорит (для 301 и 302):
Полезная нагрузка ответа сервера обычно содержит короткую гипертекстовую заметку с гиперссылкой на новый(ие) URI.
Полезная нагрузка ответа сервера обычно содержит короткую гипертекстовую заметку с гиперссылкой на различные URI.
решение2
Да, ты можешьАБСОЛЮТНОсделайте это с NGINX!
Просто установите обработчик исключений, также известный как
error_page
, для постобработки требуемых ответов. Обязательно установите его таким образом, чтобы предотвратить изменение страницы с ошибкой кода статуса HTTP, например, не используйте параметр=
(или используйте его для жесткого кодирования любого желаемого вами кода).Убедись в
return
ответ с кодом статуса возврата, который позволяет вам опционально установить[text]
, а неURL
.Указать
default_type
из""
, который, по-видимому, удаляетContent-Type
заголовок
Вот полный код, также у меняGitHubвStackOverflow.cnst.nginx.conf
репозиторий:
# cat sf.421976.301-302-redirect-w-no-http-body-text.nginx.conf | sed 's#^#\t#g'
server {
listen 1976;
error_page 301 302 @30x; # keep original HTTP status code w/o `=`
location @30x {
default_type ""; # will remove Content-Type completely
# `300` is a filler: client will get the original HTTP status code
return 300;
}
return 301 http://example.su/test;
}
Вот подтверждение того, что все работает правильно:
% curl -i localhost:1976 | sed 's#^#\t#g'
HTTP/1.1 301 Moved Permanently
Server: nginx/1.2.1
Date: Mon, 28 Aug 2017 22:02:41 GMT
Content-Length: 0
Connection: keep-alive
Location: http://example.su/test
%
Я попробовал это в браузерах, и там тоже все отлично работает.
PS Другой вариант — изменить исходный код и отредактироватьngx_http_error_301_page
и другие переменные, но зачем идти сложным путем?! ^_^
решение3
Это немного уродливо, но, возможно, вы могли бы проксировать запросы 301/302 и использовать proxy_method для изменения запросов GET на HEAD. Я не проверял, но запросы head должны отправлять только заголовки без ответов или (надеюсь) заголовки content-*.