NGINX 301 и 302 обслуживают небольшое тело документа nginx. Есть ли способ убрать это поведение?

NGINX 301 и 302 обслуживают небольшое тело документа nginx. Есть ли способ убрать это поведение?

Мы заметили, что при использовании внутренней обработки 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-*.

http://wiki.nginx.org/NginxHttpProxyModule#proxy_method

Связанный контент