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

Мы заметили, что при использовании внутренней обработки 301 и 302 nginx nginx будет обслуживать небольшое тело документа с соответствующим заголовком Location: ....

Что-то вроде (в html): 301 редирект - nginx.

В зависимости от вышеприведенного поведения, также отправляются заголовки text/html и content-length типа контента.

Мы делаем 302 и около 301 переадресацию, вышеупомянутое поведение, по нашему мнению, является пустой тратой пропускной способности.

Есть ли способ отключить это поведение?

Одна мысль, которая пришла нам в голову, состояла в том, чтобы установить error_page 301 302 в пустой текстовый файл. Мы еще не проверяли это, но я предполагаю, что даже с учетом вышесказанного будут отправлены заголовки content-type и content-length (0).

Итак, есть ли чистый способ отправить "без тела" 301/302 редирект с помощью nginx?

3 ответа

Решение

Подумайте очень внимательно о том, что вы просите, и решительно не делайте этого.

В RFC 2616 указано, что должны присутствовать тела сущностей, которые вы хотите удалить.

10.3.2 301 постоянно перемещено

Новый постоянный URI ДОЛЖЕН быть задан в поле Location в ответе. Если метод запроса не является HEAD, объект ответа ДОЛЖЕН содержать краткую гипертекстовую заметку с гиперссылкой на новый URI.

а также...

10.3.3 302 найдено

Временный URI ДОЛЖЕН быть задан полем Location в ответе. Если метод запроса не является HEAD, объект ответа ДОЛЖЕН содержать краткую гипертекстовую заметку с гиперссылкой на новый URI.

СЛЕДУЕТ в этом контексте определять в RFC 2119:

Это слово или прилагательное "РЕКОМЕНДУЕТСЯ" означают, что в определенных обстоятельствах могут существовать веские причины игнорировать конкретный элемент, но перед тем, как выбрать другой курс, необходимо понять все последствия и тщательно взвесить их.

Теперь вы можете сделать это, не нарушая RFC, но вы должны понимать все последствия:

  • Вы делаете много работы практически без пользы. Единственная логическая причина, по которой я могу придумать отключение тела объекта, - это сэкономить на затратах на полосу пропускания, и на самом деле это причина, о которой вы упомянули, но разница настолько минимальна, что вряд ли вы даже увидите разницу в графиках полосы пропускания.
  • Очень небольшая часть веб-клиентов не выполняет автоматически 3xx-перенаправления. Эта фракция была намного больше, когда был написан RFC, именно поэтому это и есть в первую очередь, но все еще существуют древние чудовища, скрывающиеся в тени темных спален и шкафов центров обработки данных, и иногда они выходят на сцену. Тот, который вы, скорее всего, увидите curl, который до сих пор в общем пользовании.

Эта рекомендация была несколько смягчена с RFC 7231, который просто говорит (для 301 и 302):

Ответная полезная нагрузка сервера обычно содержит короткую гипертекстовую заметку с гиперссылкой на новый URI.

Ответная полезная нагрузка сервера обычно содержит короткую гипертекстовую заметку с гиперссылкой на различные URI.

Да, вы можете АБСОЛЮТНО делать это с 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 и т.д. переменные, но зачем идти сложным путем?! ^_^

Это немного уродливо, но, возможно, вы могли бы прокси-запросы 301/302 и использовать proxy_method, чтобы изменить GET на HEAD-запросы. Я не проверял это, но запросы заголовков должны отправлять только заголовки без ответов или (мы надеемся) заголовки содержимого -*.

http://wiki.nginx.org/NginxHttpProxyModule

Другие вопросы по тегам