Znaki dozwolone w adresie URL


191

Czy ktoś zna pełną listę znaków, których można używać w ramach GET bez kodowania? W tej chwili używam AZ az i 0-9 ... ale szukam pełnej listy.

Interesuje mnie również to, czy wydano specyfikację dla nadchodzącego dodatku chińskiego, arabskiego adresu URL (co oczywiście będzie miało duży wpływ na moje pytanie)


5
Znaki dozwolone w identyfikatorze URI są zarezerwowane !*'();:@&=+$,/?#[]lub niezarezerwowane A-Za-z0-9_.~-(lub znak procentowy %jako część kodowania procentowego)
Mikl

1
W MySQL używam tego, REGEXP '[^]A-Za-z0-9_.~!*''();:@&=+$,/?#[%-]+'aby znaleźć ciąg URL ze złymi znakami. Może to też jest przydatne dla kogoś innego.
Mikl

@Mikl: Ta rzecz nie wygląda jak wyrażenie regularne.
Jens Mander

Odpowiedzi:


182

Ze specyfikacji RFC 1738 :

Dlatego tylko $-_.+!*'(),adresy alfanumeryczne, znaki specjalne „ ” i znaki zastrzeżone używane do ich zarezerwowanych celów mogą być użyte w postaci niezakodowanej w adresie URL.

EDYCJA: Jak słusznie zauważa @Jukka K. Korpela, ten RFC został zaktualizowany przez RFC 3986 . To rozszerzyło i wyjaśniło znaki ważne dla hosta, niestety nie jest łatwo kopiowane i wklejane, ale dam z siebie wszystko.

W pierwszej kolejności:

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
@ Ukośnik czasowy jest znakiem zastrzeżonym, dlatego jeśli jest używany do swojego zarezerwowanego celu (wyznaczanie ścieżek, wyznaczanie protokołu ...), nie musi uciekać. W przeciwnym razie tak jest.
Myles,

4
Ogólne zasady składni RFC 1738 zostały przestarzałe w 1998 r.
Jukka K. Korpela,

3
@Myles, STD 66 (= RFC 3986) jest wymieniony w innych odpowiedziach. To, czy treść odpowiedzi jest poprawna, to inna kwestia; Nie sądzę, aby którakolwiek z odpowiedzi poprawnie opisywała pełną listę.
Jukka K. Korpela,

4
I możesz dodać listę A-Za-z0-9_.-~niezarezerwowanych i zarezerwowanych znaków na początku tej odpowiedzi. !*'();:@&=+$,/?#[]Może zaoszczędzić czas ludziom
Mikl

2
@basZero Przykro mi, że uznałeś to za mylące, ale pełna odpowiedź nie jest prosta. Odpowiedź na twoje pytanie brzmi „nie”, ponieważ jest to znak zastrzeżony, jak stwierdził:reserved = gen-delims / sub-delims gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@"
Myles,

42

Znaki dozwolone w identyfikatorze URI są zarezerwowane lub niezarezerwowane (lub znak procentowy jako część kodowania procentowego)

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

mówi to RFC 3986 znaków bezwarunkowe (s. 2,3), a także znaków zastrzeżonych (sec 2.2), jeśli trzeba zachować swoje szczególne znaczenie. A także znak procentowy jako część kodowania procentowego.


7
Chociaż ten link może odpowiedzieć na pytanie, lepiej dołączyć tutaj istotne części odpowiedzi i podać link w celach informacyjnych. Odpowiedzi zawierające tylko łącze mogą stać się nieprawidłowe, jeśli zmieni się połączona strona.
jaestevan

@jaestevan Cytat z powiązanego dokumentu:The characters allowed in a URI are either reserved or unreserved (or a percent character as part of a percent-encoding)
Mikl

26

Pełna lista 66 niezarezerwowanych znaków znajduje się w RFC3986, tutaj: http://tools.ietf.org/html/rfc3986#section-2.3

Jest to dowolny znak w następującym zestawie wyrażeń regularnych:

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

2
Możesz również użyć tych zarezerwowanych.
Qwerty

Przestarzałe RFC1738 wymienione {}^\~i backtickjako niebezpieczne. A RFC3986 wymienia \ jako niebezpieczne ze względu na system plików. Można to {}^również wykorzystać.
mgutt

Więc jeśli próbujesz, powiedzmy, znaleźć koniec adresu URL w ciągu znaków (którym jestem), najlepiej zastosować przestarzałe standardy w przyjętej odpowiedzi ... Jeśli weryfikujesz adres URL , powinieneś użyj zestawu znaków w tej odpowiedzi.
ashleedawg

Ostrożnie, napisałeś to jako klasę wyrażeń regularnych. Pamiętaj, aby uciec -lub umieścić go na początku lub na końcu klasy postaci, ponieważ[.-~] faktycznie zawiera wszystkie znaki ASCII od 46 do 126.
kwl

19

Przetestowałem to, prosząc moją stronę internetową (apache) o wszystkie dostępne znaki na mojej niemieckiej klawiaturze jako parametr adresu URL:

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

Nie zostały one zakodowane:

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

Nie zakodowany po urlencode():

0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.-_

Nie zakodowany po rawurlencode():

0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.-_~

Uwaga: przed PHP 5.3.0 rawurlencode() zakodowany z ~powodu RFC 1738 . Ale został zastąpiony przez RFC 3986, więc teraz jest bezpieczny w użyciu. Ale nie rozumiem, dlaczego na przykład {}są kodowane, rawurlencode()ponieważ nie są wymienione w RFC 3986.

Dodatkowy test, który przeprowadziłem, dotyczył automatycznego linkowania w wiadomościach e-mail. Przetestowałem Mozilla Thunderbird, aol.com, outlook.com, gmail.com, gmx.de i yahoo.de i w pełni powiązane adresy URL zawierające te znaki:

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

Oczywiście również ?był powiązany, ale tylko jeśli był użyty raz.

Niektórzy sugerują teraz używanie tylko rawurlencode()znaków, ale czy słyszałeś kiedyś, że ktoś miał problemy z otwarciem tych stron?

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

Dwukropek
https://en.wikipedia.org/wiki/Wikipedia:About

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

Na znak, dwukropek, przecinek i wykrzyknik
https: //www.google.com/maps/place/USA/@36.2218457, ...

Z tego powodu te znaki powinny być użyteczne bez zakodowania. Oczywiście nie powinieneś używać&; powodu takich sekwencji kodujących &amp;. Ten sam powód obowiązuje, %ponieważ był używany do kodowania znaków w ogóle. I =ponieważ przypisuje wartość do nazwy parametru.

Na koniec powiedziałbym, że można używać tych niezakodowanych:

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

Ale jeśli oczekujesz losowo generowanych adresów URL, nie powinieneś ich używać .!, ponieważ oznaczają one koniec zdania, a niektóre aplikacje pocztowe nie łączą automatycznie ostatniego znaku adresu URL. Przykład:

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

Praktyczne podejście - dobra robota. Szukałem twojej ostatniej listy - +szczególnie znaku :-D
Oliver

12

od tutaj

Tak więc tylko $-_.+!*'(), adresy alfanumeryczne, znaki specjalne i znaki zastrzeżone używane do ich zarezerwowanych celów mogą być użyte w postaci niezakodowanej w adresie URL.



6

RFC3986 definiuje dwa zestawy znaków, których można użyć w URI:

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

    zastrzeżone = gen-delims / sub-delims

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

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

    Celem znaków zastrzeżonych jest zapewnienie zestawu znaków ograniczających, które można odróżnić od innych danych w URI. Identyfikatory URI, które różnią się pod względem zamiany znaku zastrzeżonego na odpowiadający mu oktet zakodowany w procentach, nie są równoważne.

  • Niezarezerwowane postacie :A-Za-z0-9-_.~

    unreserved = ALPHA / DIGIT / "-" / "." / „_” / „~”

    Znaki, które są dozwolone w URI, ale nie mają zarezerwowanego celu, nazywane są niezarezerwowanymi.


3

Nadchodząca zmiana dotyczy chińskich, arabskich nazw domen, a nie URI. Umiędzynarodowione URI są nazywane IRI i są zdefiniowane w RFC 3987 . Jednak powiedziawszy, że zalecałbym nie robić tego sam, ale polegać na istniejącej, przetestowanej bibliotece, ponieważ istnieje wiele możliwości kodowania / dekodowania URI i tego, co jest uważane za bezpieczne według specyfikacji, w porównaniu do tego, co jest bezpieczne przy rzeczywistym użyciu (przeglądarki) .


0

Jeśli chcesz dać użytkownikom wyjątkowe wrażenia, możesz użyć pushStatedo wprowadzenia szerokiej gamy znaków do adresu URL przeglądarki:

wprowadź opis zdjęcia tutaj

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);
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.