Percebemos que ao usar o tratamento interno 301 e 302 do nginx, o nginx servirá um pequeno corpo de documento com o cabeçalho Location: ... apropriado.
Algo parecido com (em html): redirecionamento 301 - nginx.
Conforme apropriado no comportamento acima, um cabeçalho de tipo de conteúdo texto/html e comprimento de conteúdo também é enviado.
Fazemos muitos redirecionamentos 302 e alguns 301. O comportamento acima é um desperdício de largura de banda em nossa opinião.
Alguma maneira de desativar esse comportamento?
Uma ideia que passou pela nossa cabeça foi definir error_page 301 302 como um arquivo de texto vazio. Ainda não testamos isso, mas presumo que mesmo com o exposto acima, os cabeçalhos content-type e content-length (0) serão enviados.
Então, existe uma maneira limpa de enviar um redirecionamento 301/302 "sem corpo" com o nginx?
Responder1
Pense com muito cuidado sobre o que você está pedindo e considere fortementenão fazendo isso.
RFC 2616especifica que os corpos da entidade que você deseja remover devem estar presentes.
10.3.2 301 Movido Permanentemente
O novo URI permanente DEVE ser fornecido pelo campo Localização na resposta. A menos que o método de solicitação seja HEAD, a entidade da resposta DEVE conter uma breve nota de hipertexto com um hiperlink para o(s) novo(s) URI(s).
e...
10.3.3 302 Encontrado
O URI temporário DEVE ser fornecido pelo campo Localização na resposta. A menos que o método de solicitação seja HEAD, a entidade da resposta DEVE conter uma breve nota de hipertexto com um hiperlink para o(s) novo(s) URI(s).
DEVERIA, neste contexto, é definido emRFC 2119:
Esta palavra, ou o adjetivo “RECOMENDADO”, significa que podem existir razões válidas em circunstâncias específicas para ignorar um item específico, mas todas as implicações devem ser compreendidas e cuidadosamente ponderadas antes de escolher um caminho diferente.
Agora você pode fazer isso sem violar a RFC, mas deve estar ciente de todas as implicações:
- Você está trabalhando muito sem praticamente nenhum benefício. A única razão lógica que consigo pensar para desabilitar o corpo da entidade é economizar nos custos de largura de banda e, de fato, esse é o motivo que você mencionou, mas a diferença é tão mínima que é improvável que você veja uma diferença em seus gráficos de largura de banda.
- Uma fração muito pequena de clientes da web não segue automaticamente os redirecionamentos 3xx. Essa fração era muito maior quando a RFC foi escrita, e é por isso que ela existe, em primeiro lugar, mas ainda existem monstruosidades antigas à espreita nas sombras de quartos escuros e armários de data centers, e às vezes elas saem para brincar. O que você provavelmente verá é o
curl
, que ainda é de uso comum.
Esta recomendação foi um pouco relaxada comRFC 7231, que apenas diz (para 301 e 302):
A carga de resposta do servidor geralmente contém uma breve nota de hipertexto com um hiperlink para o(s) novo(s) URI(s).
A carga de resposta do servidor geralmente contém uma breve nota de hipertexto com um hiperlink para os diferentes URI(s).
Responder2
Sim você podeABSOLUTAMENTEfaça isso com NGINX!
Basta instalar um manipulador de exceções, também conhecido como
error_page
, para pós-processar as respostas necessárias. Certifique-se de configurá-lo de forma a evitar que a página de erro modifique o código de status HTTP, por exemplo, não use o=
parâmetro (ou use-o para codificar qualquer código que desejar).Tenha certeza de
return
uma resposta com um código de status de retorno que permite definir opcionalmente o[text]
, não oURL
.Especificamos
default_type
of""
, que parece remover oContent-Type
cabeçalho
Aqui está o código completo, também no meuGitHubemStackOverflow.cnst.nginx.conf
repositório:
# 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;
}
Aqui está a confirmação de que está funcionando corretamente:
% 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
%
Eu tentei nos navegadores e funcionou bem lá também.
PS Outra opção seria modificar o código fonte e editar ongx_http_error_301_page
e outras variáveis, mas por que seguir o caminho difícil?! ^_^
Responder3
É um pouco feio, mas talvez você possa fazer proxy de solicitações 301/302 e usar o proxy_method para alterar solicitações GET para HEAD. Não testei, mas as solicitações principais devem enviar apenas cabeçalhos sem respostas ou (espero) cabeçalhos content-*.