2013-12-09 10 views
12

Mam problem z moim serwerem. Mam cztery linków do różnych stron mojego dynamicznej strony internetowej, które wyglądają mniej więcej tak:Linki zewnętrzne Kodowanie adresu URL prowadzi do "% 3F" i "% 3D" na serwerze Nginx

myurl.com/default/Site%3Fid%3D13 

Powinny one wyglądać tak:

myurl.com/default/Site?id=13 

wiem, że ci %3F jest sekwencja ucieczki dla ? znak i %3D to sekwencja escape dla znaku równości. Ale otrzymuję błąd 400, gdy używam tych linków. Co mogę z tym zrobić?

Cztery linki są dla różnych stron i wyobrażam sobie, że z czasem będzie więcej takich linków. Tak więc jedna poprawka dla wszystkich byłaby doskonała.

+0

@John tylko w przypadku zapomnienia i nie zauważył, The Bounty ustawieniu będzie wygaśnie w ciągu kilka godzin. –

Odpowiedz

8

Dokładna samo pytanie zostało faktycznie zapytał na liście dyskusyjnej nginx-ru około rok temu:

http://mailman.nginx.org/pipermail/nginx-ru/2013-February/050200.html

Najbardziej pomocne odpowiedzi, przez Nginx, Inc, pracownika/programista Валентин Бартенев:

http://mailman.nginx.org/pipermail/nginx-ru/2013-February/050209.html

Если запрос приходит в таком виде, то это уже не парам тры, а имя запрошенного файла. Другое дело, что location ищется по уже раскодированному адресу, о чем в документации написано.

Tłumaczenie:

Jeżeli żądanie jest w takiej formie, to już nie są te argumenty, ale nazwa żądanego pliku. Inną rzeczą jest to, że zgodnie z dokumentacją dopasowywanie lokalizacji odbywa się w stosunku do znormalizowanego URI.

Jego proponowane rozwiązanie, tłumaczone na przykład próbki stąd pytanie na SO, będzie wówczas:

location /default/Site? { 
    rewrite \?(.*)$ /default/Site?$1? last; 
} 

location = /default/Site { 
    [...] 
} 
+0

@John and user3082653 - Czy jest coś o mojej odpowiedzi, która jest niejasna lub wymaga dalszych wyjaśnień? – cnst

0

URL jest całkowicie poprawny. Ukryte znaki, które zawiera, są unikalne. Co jest w porządku.

Celem jest to, że w rzeczywistości można podać nazwę żądania (w większości przypadków odpowiadającą nazwie pliku na dysku), która jest Site?id=13, a nie Site, a reszta jako ciąg zapytania.

Uznałbym, że złą praktyką jest posiadanie znaków w nazwie pliku, która czyni to koniecznym. Jednak w argumentach URL może być bardzo potrzebny.

Mimo to adres URL żądania jest prawidłowy i prawdopodobnie nie jest taki, jaki ma być. Co w konsekwencji sugeruje, że powinieneś poprawić błąd tam, gdzie ktoś wybrał niewłaściwy adres URL.

Nie do końca rozumiem, dlaczego pojawia się błąd 400; powinieneś raczej otrzymać błąd 404. Ale to zależy od twojej konfiguracji.

Zdarzają się również przypadki, szczególnie w przypadku nginx, które polegają głównie na przekazywaniu całych adresów URL i części adresów URL na wielu poziomach (na przykład odwrotne proxy, dopasowanie wyrażeń regularnych z adresu URL i używanie ich jako zmiennych itp.). może wystąpić błąd. Ale żeby to zweryfikować i naprawić, musielibyśmy wiedzieć więcej o twojej konfiguracji.

1

Poniższy przykładowy by przekierować wszystkie żądania nieprawidłowo prognozujące (definiowane jako mające ? w żądanym pliku — zakodowany jako %3F we wniosku) do tych mniej źle wyglądających, niezależnie od URL.

(Należy pamiętać, że, jak słusznie doradzili gdzie indziej, nie powinniście uzyskiwać tych błędnie utworzonych linków w pierwszej kolejności, więc używajcie ich w ostateczności tylko wtedy, gdy nie można poprawić błędnie utworzonych linków, wiesz, że takie wnioski są próbował przez ważnych czynników.)

server { 
    listen  [::]:80; 
    server_name localhost; 

    rewrite  ^/([^?]*)\?(.*)$ /$1?$2?  permanent; 
    location/{ 
     return 200 "id is $arg_id\n"; 
    } 
} 

jest to przykład, jak to działa — gdy żądanie niesłusznie patrząc napotkano, próba korekty jest wykonany z odpowiedzią 301 Moved Permanently z rzekomo poprawne Location nagłówek odpowiedzi, który sprawi, że przeglądarka automatycznie ponownie prześle żądanie do nowo podanej lokalizacji acji:

opti# curl -6v "http://localhost/default/Site%3Fid%3D13" 
* About to connect() to localhost port 80 (#0) 
* Trying ::1... 
* connected 
* Connected to localhost (::1) port 80 (#0) 
> GET /default/Site%3Fid%3D13 HTTP/1.1 
> User-Agent: curl/7.26.0 
> Host: localhost 
> Accept: */* 
> 
< HTTP/1.1 301 Moved Permanently 
< Server: nginx/1.4.1 
< Date: Wed, 15 Jan 2014 17:09:25 GMT 
< Content-Type: text/html 
< Content-Length: 184 
< Location: http://localhost/default/Site?id=13 
< Connection: keep-alive 
< 
<html> 
<head><title>301 Moved Permanently</title></head> 
<body bgcolor="white"> 
<center><h1>301 Moved Permanently</h1></center> 
<hr><center>nginx/1.4.1</center> 
</body> 
</html> 
* Connection #0 to host localhost left intact 
* Closing connection #0 

Zauważ, że żadne próby korekty wykonywane są na właściwych wyglądające wniosków:

opti# curl -6v "http://localhost/default/Site?id=13" 
* About to connect() to localhost port 80 (#0) 
* Trying ::1... 
* connected 
* Connected to localhost (::1) port 80 (#0) 
> GET /default/Site?id=13 HTTP/1.1 
> User-Agent: curl/7.26.0 
> Host: localhost 
> Accept: */* 
> 
< HTTP/1.1 200 OK 
< Server: nginx/1.4.1 
< Date: Wed, 15 Jan 2014 17:09:30 GMT 
< Content-Type: application/octet-stream 
< Content-Length: 9 
< Connection: keep-alive 
< 
id is 13 
* Connection #0 to host localhost left intact 
* Closing connection #0 
Powiązane problemy