2013-12-09 3 views
12

Ho riscontrato un problema con il mio server. Ho avuto quattro link in entrata a diversi siti della mia pagina web dinamica che simile a questa:Link esterni La codifica dell'URL porta a '% 3F' e '% 3D' sul server Nginx

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

Dovrebbero assomigliare a questo:

myurl.com/default/Site?id=13 

so che quelli %3F è una sequenza di escape per la ? e la %3D è una sequenza di escape per il segno di uguale. Ma ottengo un errore 400 quando utilizzo questi collegamenti. Cosa posso fare a riguardo?

I quattro collegamenti sono per siti diversi, e immagino che nel tempo ci saranno più collegamenti del genere. Quindi una soluzione per tutti sarebbe perfetta.

+0

@ John nel caso in cui si è dimenticato e non hai notato, la generosità si imposta sta per scadere entro poche ore. –

risposta

8

Un stessa identica questione è stato effettivamente chiesto sulla mailing list nginx-ru circa un anno fa:

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

La risposta più utili, da un Nginx, Inc, dipendente/sviluppatore, Валентин Бартенев:

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

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

Traduzione:

Se la richiesta viene in una tale forma, allora questi non sono più i args, ma il nome del file richiesto. Un'altra cosa è che, come documentato, la corrispondenza della posizione viene eseguita rispetto a un URI normalizzato.

sua soluzione proposta, tradotto per l'esempio del campione dalla questione qui a SO, sarebbe allora:

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

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

@John e user3082653 - C'è qualcosa nella mia risposta che non è chiara o richiede ulteriori chiarimenti? – cnst

0

Il URL è perfettamente valida. I personaggi fuggiti che contiene sono solo quelli, fuggiti. Che va perfettamente bene.

Lo scopo è che si possa effettivamente avere un nome di richiesta (nella maggior parte dei casi corrispondente al nome file sul disco) che è Site?id=13 e non Site e il resto come stringa di query.

Considererei una cattiva pratica avere caratteri in un nome file che lo rende necessario. Tuttavia, negli argomenti URL potrebbe essere necessario.

Tuttavia, l'URL della richiesta è valido e probabilmente non è ciò che si desidera che sia. Che di conseguenza suggeriscono di correggere l'errore ovunque qualcuno abbia individuato l'URL sbagliato in primo luogo.

Non capisco veramente perché si ottiene un errore 400; dovresti piuttosto ottenere un errore 404. Ma ciò dipende dalla tua configurazione.

Esistono anche casi, in particolare con nginx, che coinvolgono principalmente la trasmissione di interi URL e parti di URL su più livelli (ad esempio proxy inversi, corrispondenza delle espressioni regolari dall'URL e utilizzo di tali variabili come variabili, ecc.) Dove tale potrebbe verificarsi un errore Ma per verificare questo e risolverlo avremmo bisogno di sapere di più sulla tua configurazione.

1

Il seguente esempio sarebbe reindirizzare tutte le richieste erroneamente-looking (definiti come avendo ? nel nome del file richiesto — codificati come %3F nella richiesta) in quelli meno torto-looking, indipendentemente dal URL.

(Si prega di notare che, come giustamente consigliato altrove, non si dovrebbe essere sempre tali link erroneamente formate in primo luogo, quindi, utilizzarlo come ultima risorsa — solo quando non è possibile correggere i collegamenti unico dato in caso contrario, e tu sai che tali richieste siano tentati da agenti validi.)

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

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

Questo è esempio di come avrebbe funzionato — quando si incontra una richiesta a torto alla ricerca, un tentativo di correzione viene eseguita con una risposta 301 Moved Permanently con un presunto corretta Location intestazione di risposta, che farebbe reindirizzare automaticamente la richiesta al sito appena fornito zione:

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 

Si noti che nessun tentativo di correzione sono effettuati sulla corretta dall'aspetto richieste:

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