Proxy reverso de Nginx + reescrita de URL

98

O Nginx está sendo executado na porta 80 e estou usando-o para inverter URLs de proxy com o caminho /foo para a porta 3200 desta maneira:

location /foo {
                proxy_pass http://localhost:3200;
                proxy_redirect     off;
                proxy_set_header   Host $host;
}

Isso funciona bem, mas eu tenho um aplicativo na porta 3200 , para o qual não quero que o /foo inicial seja enviado. Isso é - quando eu acesso http://localhost/foo/bar , eu quero apenas /bar para ser o caminho recebido pelo aplicativo. Então, tentei adicionar esta linha ao bloco de localização acima:

rewrite ^(.*)foo(.*)$ http://localhost:3200/$2 permanent;

Isso causa o redirecionamento 302 (alteração na URL), mas eu quero 301. O que devo fazer?

    
por jeffreyveon 15.04.2012 / 19:31

4 respostas

123

Qualquer redirecionamento para localhost não faz sentido de um sistema remoto (por exemplo, o navegador da Web do cliente). Portanto, os sinalizadores de reescrita permanente (301) ou de redirecionamento (302) não são utilizáveis no seu caso.

Por favor, tente seguir a configuração usando uma regra de reescrita transparente:

location  /foo {
  rewrite /foo/(.*) /$1  break;
  proxy_pass         http://localhost:3200;
  proxy_redirect     off;
  proxy_set_header   Host $host;
}

Use curl -i para testar suas reescritas. Uma mudança muito sutil na regra pode fazer com que o nginx execute um redirecionamento.

    
por 15.04.2012 / 19:56
90

A correspondência de prefixo de local simples funciona para isso sem usar uma regra de regravação, desde que você especifique um URI na diretiva proxy_pass:

location /foo {
  proxy_pass http://localhost:3200/;
}

Observe o / adicional no final da diretiva proxy_pass . O NGINX removerá o prefixo correspondente /foo e passará o restante para o servidor de backend no URI / . Portanto, http://myserver:80/foo/bar postará no backend em http://localhost:3200/bar .

Dos documentos do NGINX no proxy_pass :

If the proxy_pass directive is specified with a URI, then when a request is passed to the server, the part of a normalized request URI matching the location is replaced by a URI specified in the directive:

    
por 29.09.2015 / 05:30
34

A maneira mais correta e a melhor prática são geralmente as seguintes:

location /foo/ {
    proxy_pass http://localhost:3200/; # note the trailing slash!
}
  • Observe a extrema importância da barra em proxy_pass , que altera automaticamente a variável $uri para ter o /foo/ na frente -end corresponde a / no backend. Não há necessidade de uma diretiva rewrite explícita.

  • Além disso, observe que o arrastando / no location também é muito importante. Sem ele, você corre o risco de ter URLs de aparência estranha em seu site em um ponto (por exemplo, um trabalho /fooen além de /foo/en ).

    Além disso, o / no location com proxy_pass também garante algum tratamento especial , conforme a documentação da diretiva location , para efetivamente causar um location = /foo {return 301 /foo/;} implícito também.

    Portanto, definindo um location com a barra à direita, você não apenas garante que os URLs de sufixo sem barra, como /fooen , não sejam válidos, mas também que /foo sem barra continue a trabalhar também.

Documentação de referência:

por 26.08.2017 / 23:12
0

tente

location /foo {
    proxy_pass http://localhost:3200/;
    ....

ou

location ^~ /foo {
    proxy_pass http://localhost:3200/;
    ....
    
por 21.01.2015 / 17:20