Nginx regra de reescrita para substituir o ponto de interrogação de querystring com sublinhado

16

Para espelhar um site inteiro como HTML estático,

Gostaria de converter URLs como http://example.com/script.php?t=12 para http://example.com/script.php_t=12 .

Observe que ? na URL está sendo convertida para _ .

Isso permitirá que o nginx ou o apache exibam esses arquivos do disco como o HTML bruto que obtivemos e salvamos de wget - um arquivo para cada URL - e não como um arquivo PHP.

É possível fazer isso por meio da regravação de URL do Nginx?

    
por Arpit Jalan 10.03.2015 / 07:57

6 respostas

14

Eu tenho esse trabalho usando try_files:

location / {
    try_files "${uri}_${args}" 404.html;
}

Isso tentará encontrar um arquivo no disco com o nome do padrão fornecido com um "_" em vez do "?".

Outras configurações dependem de como você salvou arquivos estáticos, como imagens ou folhas de estilo. Você pode adicionar um fallback tentando lê-los sem disco de formulário de string de consulta como:

location / {
    try_files "${uri}_${args}" $uri 404.html;
}
    
por 12.03.2015 / 09:52
4

Algo ao longo das linhas:

location ~ \.php$ {
  # only rewrite URL's with args
  if ($args != '') {
    rewrite .* "${uri}_${args}?" last;
  }
}
    
por 12.03.2015 / 09:41
1

Eu não acho que você conseguirá fazer isso com o nginx vanilla, mas se você estiver disposto a instalar o módulo Lua para o nginx ( link ) você pode fazer isso.

server {
    server_name so.dev;
    listen 80;

    location / {

        root /tmp;

        rewrite_by_lua '
            local uri = ngx.var.uri
            local params = ngx.req.get_uri_args(0)

            for key, value in pairs(params) do
                uri = string.format("%s_%s=%s", uri, key, value)
            end

            ngx.req.set_uri(uri)
            ngx.req.set_uri_args({})
        ';

    }
}

Testado localmente e parece fazer o que você está procurando. Se você quiser manter outros parâmetros separados por e comercial, altere o bloco rewrite_by_lua para ser

local uri = ngx.var.uri
local param_string = ""
local params = ngx.req.get_uri_args(0)
local separator = ""

for key, value in pairs(params) do
    param_string = param_string .. separator .. key .. "=" .. value
    separator = "&"
end

ngx.req.set_uri(uri .. "_" .. param_string)
ngx.req.set_uri_args({})
    
por 12.03.2015 / 13:18
1

Isso funciona no nginx / 1.6.2.

rewrite ^/.*\.php$ "${uri}_${args}";

Mas, pessoalmente, eu usaria try_files solution com um fallback para um URI original se houver algum .

try_files $uri "${uri}_${args}";

Por exemplo Se você tiver script.php no disco, ele tentará primeiro e, em seguida, se não houver nenhum, ele será igual a script.php_t=12 . try_files precisa de uma versão recente do nginx.

E se isso não for suficiente, você pode fazer isso dentro de um if :

return 301 "${uri}_${args}";
    
por 12.03.2015 / 10:27
0

O wiki diz

If you specify a ? at the end of a rewrite then Nginx will drop the original $args (arguments).

Então, rewrite ^ ${uri}_$args? last; deve funcionar.

    
por 12.03.2015 / 09:35
0

As respostas sugeridas acima devem funcionar. No entanto, você vê como o seu URL se torna sensível. Como o nginx tenta verificar se o nome do arquivo existe primeiro no servidor, qualquer parâmetro extra irá eliminá-lo.

http://example.com/script.php?t=12 // works 
http://example.com/script.php?t=12&_utm=twitter // not work

Minha sugestão é deixar o URL como está e encaminhá-lo para o arquivo correto com php. Você tem acesso ao parâmetro t .

    
por 12.03.2015 / 13:04

Tags