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-запросы. Я не проверял это, но запросы заголовков должны отправлять только заголовки без ответов или (мы надеемся) заголовки содержимого -*.