Caratteri ammessi in un URL


191

Qualcuno conosce l'elenco completo dei caratteri che possono essere utilizzati all'interno di un GET senza essere codificati? Al momento sto usando AZ az e 0-9 ... ma sto cercando di scoprire l'elenco completo.

Sono anche interessato a se è stata rilasciata una specifica per l'imminente aggiunta di url cinesi e arabi (poiché ovviamente ciò avrà un grande impatto sulla mia domanda)


5
I caratteri consentiti in un URI sono riservati !*'();:@&=+$,/?#[]o non riservati A-Za-z0-9_.~-(o un carattere percentuale %come parte di una codifica percentuale)
Mikl,

1
In MySQL lo uso REGEXP '[^]A-Za-z0-9_.~!*''();:@&=+$,/?#[%-]+'per trovare una stringa URL con caratteri non validi. Forse è utile anche per qualcun altro.
Mikl,

@Mikl: Quella cosa non sembra quasi un'espressione regolare.
Jens Mander,

Risposte:


182

Dalla specifica RFC 1738 :

Pertanto, solo i caratteri alfanumerici, i caratteri speciali " $-_.+!*'()," e i caratteri riservati utilizzati per i loro scopi riservati possono essere utilizzati non codificati all'interno di un URL.

EDIT: Come sottolinea correttamente @Jukka K. Korpela, questo RFC è stato aggiornato da RFC 3986 . Questo ha ampliato e chiarito i caratteri validi per l'host, purtroppo non è facile da copiare e incollare, ma farò del mio meglio.

Nel primo ordine abbinato:

host        = IP-literal / IPv4address / reg-name

IP-literal  = "[" ( IPv6address / IPvFuture  ) "]"

IPvFuture   = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" )

IPv6address =         6( h16 ":" ) ls32
                  /                       "::" 5( h16 ":" ) ls32
                  / [               h16 ] "::" 4( h16 ":" ) ls32
                  / [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32
                  / [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32
                  / [ *3( h16 ":" ) h16 ] "::"    h16 ":"   ls32
                  / [ *4( h16 ":" ) h16 ] "::"              ls32
                  / [ *5( h16 ":" ) h16 ] "::"              h16
                  / [ *6( h16 ":" ) h16 ] "::"

ls32        = ( h16 ":" h16 ) / IPv4address
                  ; least-significant 32 bits of address

h16         = 1*4HEXDIG 
               ; 16 bits of address represented in hexadecimal

IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet

dec-octet   = DIGIT                 ; 0-9
              / %x31-39 DIGIT         ; 10-99
              / "1" 2DIGIT            ; 100-199
              / "2" %x30-34 DIGIT     ; 200-249
              / "25" %x30-35          ; 250-255

reg-name    = *( unreserved / pct-encoded / sub-delims )

unreserved  = ALPHA / DIGIT / "-" / "." / "_" / "~"     <---This seems like a practical shortcut, most closely resembling original answer

reserved    = gen-delims / sub-delims

gen-delims  = ":" / "/" / "?" / "#" / "[" / "]" / "@"

sub-delims  = "!" / "$" / "&" / "'" / "(" / ")"
              / "*" / "+" / "," / ";" / "="

pct-encoded = "%" HEXDIG HEXDIG

5
La barra @Tim è un carattere riservato, quindi, se viene utilizzata per il suo scopo riservato (delineare percorsi, delineare il protocollo ...), allora non ha bisogno di uscire. Altrimenti, lo fa.
Myles,

4
Le regole di sintassi generiche di RFC 1738 erano obsolete nel 1998.
Jukka K. Korpela

3
@Myles, STD 66 (= RFC 3986) è menzionato in altre risposte. Se il contenuto delle risposte è corretto è un'altra questione; Non credo che nessuna delle risposte descriva correttamente l'elenco completo.
Jukka K. Korpela,

4
E puoi aggiungere un elenco di A-Za-z0-9_.-~caratteri non prenotati e riservati all'inizio di questa risposta. !*'();:@&=+$,/?#[]Può risparmiare tempo per le persone
Mikl,

2
@basZero Mi dispiace che tu l'abbia trovato confuso, ma la risposta completa non è semplice. La risposta alla tua domanda è no, in quanto è un personaggio riservato come affermato da:reserved = gen-delims / sub-delims gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@"
Myles

42

I caratteri consentiti in un URI sono riservati o non riservati (o un carattere percentuale come parte di una codifica percentuale)

http://en.wikipedia.org/wiki/Percent-encoding#Types_of_URI_characters

afferma che si tratta di caratteri senza prenotazione RFC 3986 (sec. 2.3) e di caratteri riservati (sec. 2.2) se devono conservare il loro significato speciale. E anche un carattere percentuale come parte di una codifica percentuale.


7
Sebbene questo collegamento possa rispondere alla domanda, è meglio includere qui le parti essenziali della risposta e fornire il collegamento come riferimento. Le risposte di solo collegamento possono diventare non valide se la pagina collegata cambia.
Jaestevan,

@jaestevan Citazione dal documento collegato:The characters allowed in a URI are either reserved or unreserved (or a percent character as part of a percent-encoding)
Mikl

26

L'elenco completo dei 66 caratteri senza prenotazione è in RFC3986, qui: http://tools.ietf.org/html/rfc3986#section-2.3

Questo è qualsiasi carattere nel seguente set regex:

[A-Za-z0-9_.\-~]

2
Puoi usare anche quelli riservati.
Qwerty,

Il obsoleto RFC1738 elencato {}^\~e backtickcome non sicuro. E RFC3986 elenca \ come non sicuro a causa del file system. Questo significa che {}^potrebbe anche essere usato.
mgutt,

Quindi se stai cercando, per esempio, di trovare la fine di un url all'interno di una stringa (che io sono), sarebbe meglio seguire gli standard obsoleti nella risposta accettata ... Se stai convalidando l'URL dovresti usa l'insieme di caratteri su questa risposta.
ashleedawg,

Attenzione, hai scritto questo come una classe di caratteri di espressione regolare. Assicurati di sfuggire -o metterlo all'inizio o alla fine della classe di caratteri, perché in [.-~]realtà contiene tutti i caratteri ASCII da 46 a 126.
kwl

19

L'ho testato richiedendo il mio sito Web (apache) con tutti i caratteri disponibili sulla mia tastiera tedesca come parametro URL:

http://example.com/?^1234567890ß´qwertzuiopü+asdfghjklöä#<yxcvbnm,.-°!"§$%&/()=? `QWERTZUIOPÜ*ASDFGHJKLÖÄ\'>YXCVBNM;:_²³{[]}\|µ@€~

Questi non sono stati codificati:

^0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ,.-!/()=?`*;:_{}[]\|~

Non codificato dopo urlencode():

0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.-_

Non codificato dopo rawurlencode():

0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.-_~

Nota: prima di PHP 5.3.0 rawurlencode()codificato a ~causa di RFC 1738 . Ma questo è stato sostituito da RFC 3986 quindi è sicuro da usare, ora. Ma non capisco perché ad esempio {}vengano codificatirawurlencode() perché non menzionati in RFC 3986.

Un ulteriore test che ho fatto riguardava il collegamento automatico nei messaggi di posta. Ho testato Mozilla Thunderbird, aol.com, outlook.com, gmail.com, gmx.de e yahoo.de e hanno completamente collegato URL contenenti questi caratteri:

0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.-_~+#,%&=*;:@

Naturalmente il ? link era collegato, ma solo se usato una volta.

Alcune persone ora suggeriscono di usare solo il file rawurlencode() caratteri, ma hai mai sentito che qualcuno ha avuto problemi ad aprire questi siti Web?

Asterisco
http://wayback.archive.org/web/*/http://google.com

Due punti
https://en.wikipedia.org/wiki/Wikipedia:About

Inoltre
https://plus.google.com/+google

A segno, due punti, virgola e punto esclamativo
https: //www.google.com/maps/place/USA/@36.2218457, ...

Per questo motivo questi caratteri devono essere utilizzabili senza codifica senza problemi. Naturalmente non dovresti usare a &;causa della codifica di sequenze come &amp;. Lo stesso motivo è valido in %quanto utilizzato per codificare i caratteri in generale. E= poiché assegna un valore al nome di un parametro.

Infine, direi che va bene usare questi non codificati:

0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.-_~!+,*:@

Ma se ti aspetti che gli URL generati casualmente non dovresti usare .!, perché quelli segnano la fine di una frase e alcune app di posta non collegheranno automaticamente l'ultimo carattere dell'URL. Esempio:

Visit http://example.com/foo=bar! !

Approccio pratico - buon lavoro. Stavo cercando l'ultimo tuo elenco - il +segno in particolare MrGreen
Oliver

12

Da qui

Pertanto, solo i caratteri alfanumerici, i caratteri speciali $-_.+!*'(), e i caratteri riservati utilizzati per i loro scopi riservati possono essere utilizzati non codificati all'interno di un URL.



6

RFC3986 definisce due serie di caratteri che è possibile utilizzare in un URI:

  • Personaggi riservati ::/?#[]@!$&'()*+,;=

    riservato = gen-delims / sub-delim

    gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@"

    sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="

    Lo scopo dei caratteri riservati è di fornire un set di caratteri delimitanti che siano distinguibili da altri dati all'interno di un URI. Gli URI che differiscono nella sostituzione di un carattere riservato con il corrispondente ottetto con codifica percentuale non sono equivalenti.

  • Personaggi senza prenotazione :A-Za-z0-9-_.~

    senza prenotazione = ALPHA / DIGIT / "-" / "." / "_" / "~"

    I caratteri consentiti in un URI ma che non hanno uno scopo riservato sono chiamati senza prenotazione.


3

L'imminente modifica riguarda i nomi di dominio cinesi e arabi, non gli URI. Gli URI internazionalizzati sono chiamati IRI e sono definiti in RFC 3987 . Tuttavia, dopo aver detto che consiglierei di non farlo da soli, ma di fare affidamento su una libreria esistente e testata poiché ci sono molte scelte di codifica / decodifica URI e ciò che è considerato sicuro dalle specifiche, rispetto a ciò che è sicuro dall'uso effettivo (browser) .


0

Se ti piace offrire un tipo speciale di esperienza agli utenti, puoi utilizzare pushStateper portare una vasta gamma di caratteri all'URL del browser:

inserisci qui la descrizione dell'immagine

var u="";var tt=168;
for(var i=0; i< 250;i++){
 var x = i+250*tt;
console.log(x);
 var c = String.fromCharCode(x);
 u+=c; 
}
history.pushState({},"",250*tt+u);
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.