2015-01-22 3 views
6

Я обнаружил, что $ request_uri nginx дублирует параметры запроса.

К цели, которую я хочу достичь, является перенаправление любого запроса голого домена на домен www. Вот пример конфигурации.

server { 
     listen  8080; 
     server_name localhost;  
     location/{ 
      if ($http_host !~* "^www\.") { 
       rewrite (.*) http://www.$http_host$request_uri permanent; 
      } 
     } 
    } 

В результате я получил это:

curl -I http://127.0.0.1:8080/pp/\?a\=b 

HTTP/1.1 301 Moved Permanently 
Server: nginx/1.6.2 
Date: Thu, 22 Jan 2015 04:07:39 GMT 
Content-Type: text/html 
Content-Length: 184 
Connection: keep-alive 
Location: http://www.127.0.0.1:8080/pp/?a=b?a=b 

Параметр запроса дублируется в результате; я что-то упустил?

+0

Вы нашли решение? – dgilperez

+1

Это должно быть перемещено в ServerFault. http://serverfault.com/ –

ответ

2

if is evil (не всегда, но), так почему бы не попробовать вернуть 301:

server { 
    server_name example.com; 
    return 301 $scheme://www.example.com$request_uri; 
} 

server { 
    server_name www.example.com; 
    root /var/www; 
    location/{ 
    index index.html; 
    } 
} 
+0

Хм мне кажется, что это не имеет никакого отношения к '' if'', но меняет директиву '' rewrite'' для '' return 301''. В моем случае у меня нет ifs, но переписывание одинаково, и ваш вариант работает для меня. Любая идея, почему '' return'' работает и '' rewrite'', нет? Как бы вы написали это с помощью '' rewrite''? – dgilperez

+3

return 301 лучше практиковать, а затем переписать, поэтому я использую return в моем примере :) –

+2

Я улучшил ваш код, чтобы использовать '$ scheme' вместо hardcoding' http: // 'в URL-адресе перенаправления, таким образом, пример бесперебойно работают как для HTTP, так и для HTTPS. –

9

Репликация параметров запроса, которые вы видите это ожидаемое поведение Nginx. Чтобы изменить это, вам нужно добавить косую ? к переписывают как в:

server { 
     listen  8080; 
     server_name localhost;  
     location/{ 
      if ($http_host !~* "^www\.") { 
       rewrite (.*) http://www.$http_host$request_uri? permanent; 
      } 
     } 
    } 

See Documentation Here.

Если строка замены содержит новые аргументы запроса, после них добавляются аргументы предыдущего запроса . Если это нежелательна, поставив знак вопроса в конце строки замены избавляет от необходимости их добавляется, например:

переписать ^/пользователей /(.*)$/показать пользователю = $ 1? последний;

Однако конфигурация задается Алексей Дерягиным является лучшим и более эффективным вариантом для требуемого типа переадресации, потому что каждый запрос будет оцениваться if блоком в исходной конфигурации нужно ли или нет.

+0

Спасибо! Просто уточнить: если вы добавили трейлинг-'' '' к переписыванию, вся строка запроса будет удалена, или она не будет дублироваться? т. е. с конечным «?», будет ли URL-адрес «http: //www.127.0.0.1: 8080/pp /? a = b''? – dgilperez

+0

Сокращенный для ненужного использования перезаписи URL. –

+0

@dgilperez URL-адрес должен быть http: //www.127.0.0.1: 8080/pp /? A = b'. Добавление завершающего '?' Просто прекращает добавление строки запроса во второй раз. Как я уже упоминал в своем ответе, использование метода перезаписи в этом конкретном случае не является наиболее эффективным способом для этого типа перенаправления. – Dayo

Смежные вопросы