Które znaki powodują, że adres URL jest nieprawidłowy?
Czy to są prawidłowe adresy URL?
example.com/file[/].html
http://example.com/file[/].html
validation
url
rfc3986
dobrze
źródło
źródło
Odpowiedzi:
Zasadniczo identyfikatory URI zdefiniowane w RFC 3986 (patrz sekcja 2: Znaki ) mogą zawierać dowolny z następujących 84 znaków:
Zauważ, że ta lista nie określa, gdzie w URI mogą wystąpić te znaki.
Każdy inny znak musi być zakodowany za pomocą metody procentowej (
%
hh
). Każda część identyfikatora URI ma dalsze ograniczenia dotyczące tego, jakie znaki muszą być reprezentowane przez słowo zakodowane w procentach.źródło
/^([!#$&-;=?-[]_a-z~]|%[0-9a-fA-F]{2})+$/
Czy było coś, co odkryłeś, że powinno to akceptować? (Żeby było jasne, to wyrażenie regularne sprawdza tylko, czy ciąg zawiera prawidłowe znaki adresu URL, a nie czy ciąg zawiera dobrze sformułowany adres URL.)Aby dodać wyjaśnienia i bezpośrednio odpowiedzieć na powyższe pytanie, istnieje kilka klas znaków, które powodują problemy z adresami URL i identyfikatorami URI.
Niektóre znaki są niedozwolone i nigdy nie powinny pojawiać się w adresie URL / URI, znakach zastrzeżonych (opisanych poniżej) i innych znakach, które mogą powodować problemy w niektórych przypadkach, ale są oznaczone jako „nierozsądne” lub „niebezpieczne”. Wyjaśnienia, dlaczego znaki są ograniczone, są jasno określone w RFC-1738 (adresy URL) i RFC-2396 (URI). Uwaga: nowsza wersja RFC-3986 (aktualizacja RFC-1738) definiuje konstrukcję dozwolonych znaków w danym kontekście, ale starsza specyfikacja oferuje prostszy i bardziej ogólny opis, które znaki są niedozwolone przy zastosowaniu następujących reguł.
Wykluczone znaki US-ASCII niedozwolone w składni URI:
Znak „#” jest wykluczony, ponieważ służy do oddzielenia identyfikatora URI od identyfikatora fragmentu. Znak procentu „%” jest wykluczony, ponieważ jest używany do kodowania znaków specjalnych. Innymi słowy, „#” i „%” są znakami zastrzeżonymi, których należy użyć w określonym kontekście.
Lista niemądrych znaków jest dozwolona, ale może powodować problemy:
Znaki zastrzeżone w komponencie zapytania i / lub mające specjalne znaczenie w URI / URL:
„Zarezerwowana” klasa składni powyżej odnosi się do tych znaków, które są dozwolone w ramach identyfikatora URI, ale które mogą nie być dozwolone w ramach określonego komponentu ogólnej składni URI. Znaki w zestawie „zastrzeżone” nie są zarezerwowane we wszystkich kontekstach . Na przykład nazwa hosta może zawierać opcjonalną nazwę użytkownika, więc może to być coś w rodzaju,
ftp://user@hostname/
gdzie znak „@” ma specjalne znaczenie.Oto przykład adresu URL, który zawiera niepoprawne i nierozsądne znaki (np. „$”, „[”, „]”) I powinien być odpowiednio zakodowany:
Niektóre ograniczenia znaków dla identyfikatorów URI / adresów URL zależą od języka programowania. Na przykład „|” (0x7C), chociaż tylko oznaczony jako „nierozsądny” w specyfikacji URI, wyrzuci wyjątek URISyntaxException do konstruktora Java java.net.URI, więc adres URL podobny
http://api.google.com/q?exp=a|b
jest niedozwolony i zamiast tego należy go zakodować, tak jakhttp://api.google.com/q?exp=a%7Cb
przy użyciu Java z instancją obiektu URI.źródło
?
jest w porządku w sekcji zapytania, ale przedtem jest niemożliwa i nie sądzę, że@
należy do żadnej z tych list. Aha, a nie%25
w ostatnim ciągu, nie masz na myśli%7C
?Większość istniejących tutaj odpowiedzi jest niepraktyczna, ponieważ całkowicie ignorują rzeczywiste użycie adresów, takich jak:
Najpierw dygresja w terminologii. Jakie są te adresy? Czy są to prawidłowe adresy URL?
Historycznie odpowiedź brzmiała „nie”. Zgodnie z RFC 3986 od 2005 r. Takie adresy nie są identyfikatorami URI (a zatem nie są adresami URL, ponieważ adresy URL są rodzajem identyfikatorów URI ). Zgodnie z terminologią standardów IETF z 2005 r. Powinniśmy właściwie nazywać je IRI (Internacjonalizowane identyfikatory zasobów), jak zdefiniowano w RFC 3987 , które technicznie nie są identyfikatorami URI, ale mogą być konwertowane na identyfikatory URI poprzez proste kodowanie procentowe wszystkich znaków spoza ASCII w IRI .
Według współczesnej specyfikacji odpowiedź brzmi „tak”. WHATWG standardu życia po prostu klasyfikuje wszystko, czego wcześniej się nazywać „URI” lub „IRIS” AS „URL”. To wyrównuje specced terminologia z jak normalni ludzie, którzy nie czytali spec używać słowa „URL”, który był jednym z Spec za celami .
Jakie postacie są dozwolone w ramach WHATWG Living Standard?
Jakie znaki są dozwolone w nowym znaczeniu „URL”? W wielu częściach URL, takich jak ciąg kwerendy i ścieżki, mamy możliwość korzystania arbitralnych „jednostek URL” , które są
Co to są „punkty kodu URL”?
(Uwaga: lista „punktów kodu URL” nie obejmuje
%
, ale%
są one dozwolone w „Jednostkach kodu URL”, jeśli są one częścią sekwencji kodującej procentowo).Jedynym miejscem, w którym mogę dostrzec, gdzie specyfikacja pozwala na użycie dowolnego znaku spoza tego zestawu, jest host , w którym zawarte są adresy IPv6
[
i]
znaki. Gdzie indziej w adresie URL dozwolone są jednostki URL lub niektóre bardziej restrykcyjne zestawy znaków.Jakie postacie były dozwolone na podstawie starych RFC?
Ze względu na historię, a ponieważ nie została ona w pełni zbadana gdzie indziej w odpowiedziach tutaj, zbadajmy dozwoloną pod starszą parą specyfikacji.
Przede wszystkim mamy dwa typy znaków zastrzeżonych RFC 3986 :
:/?#[]@
, które są częścią ogólnej składni identyfikatora URI zdefiniowanego w RFC 3986!$&'()*+,;=
, które nie są częścią ogólnej składni RFC, ale są zarezerwowane do użycia jako składniki składniowe poszczególnych schematów URI. Na przykład, średniki i przecinki są stosowane jako część składni URI danych i&
i=
są stosowane jako część wszechobecnego?foo=bar&qux=baz
formacie w ciągi zapytania (który nie jest określony w specyfikacji RFC 3986).Dowolny z zastrzeżonych znaków powyżej może być legalnie używany w URI bez kodowania, albo w celu spełnienia ich celu składniowego, albo po prostu jako dosłowne znaki w danych w niektórych miejscach, w których takie użycie nie mogło być źle interpretowane jako znak spełniający swój cel syntaktyczny. (Na przykład, chociaż
/
ma składniowe znaczenie w adresie URL, możesz użyć go niezakodowanego w ciągu zapytania, ponieważ nie ma ono znaczenia w ciągu zapytania).RFC 3986 określa również niektóre niezarezerwowane znaki, których zawsze można użyć do przedstawienia danych bez żadnego kodowania:
abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~
Wreszcie
%
sam znak jest dopuszczony do kodowania procentowego.Że pozostawia tylko następujących znaków ASCII, które są zakazane pojawianiu się w adresie URL:
"<>\^`{|}
Każda inna postać z ASCII może legalnie występować w adresie URL.
Następnie RFC 3987 rozszerza ten zestaw niezastrzeżonych znaków o następujące zakresy znaków Unicode:
Te wybory bloków ze starej specyfikacji wydają się dziwne i arbitralne, biorąc pod uwagę najnowsze definicje bloków Unicode ; dzieje się tak prawdopodobnie dlatego, że bloki zostały dodane do dekady od czasu napisania RFC 3987.
Wreszcie, być może warto zauważyć, że sama wiedza, które znaki mogą legalnie pojawić się w adresie URL, nie wystarcza, aby rozpoznać, czy dany ciąg jest legalnym adresem URL, czy nie, ponieważ niektóre znaki są dozwolone tylko w określonych częściach adresu URL. Na przykład znaki zastrzeżone
[
i]
są legalne jako część hosta dosłownego IPv6 w adresie URL takim jak http: // [1080 :: 8: 800: 200C: 417A] / foo, ale nie są legalne w żadnym innym kontekście, więc Przykład OPhttp://example.com/file[/].html
jest nielegalny.źródło
W dodatkowym pytaniu zapytałeś, czy
www.example.com/file[/].html
jest prawidłowym adresem URL.Ten adres URL jest nieprawidłowy, ponieważ adres URL jest typem identyfikatora URI, a prawidłowy identyfikator URI musi mieć podobny schemat
http:
(patrz RFC 3986 ).Jeśli chciałeś zapytać, czy
http://www.example.com/file[/].html
jest to prawidłowy adres URL, odpowiedź brzmi „nie”, ponieważ znaki nawiasu kwadratowego są tam niepoprawne.Znaki nawiasu kwadratowego są zarezerwowane dla adresów URL w tym formacie:
http://[2001:db8:85a3::8a2e:370:7334]/foo/bar
(tzn. Literał IPv6 zamiast nazwy hosta)Warto dokładnie przeczytać RFC 3986, jeśli chcesz w pełni zrozumieć problem.
źródło
[
I]
nie są ważne przez URI prawie parserami widziałem. To mnie naprawdę wkręciło w prawdziwym świecie: stackoverflow.com/questions/11038967/...Unwise
bardzo poważnie dla URI, a mimo to będą w porządku z bibliotekami URL. Oznacza to, że nie ma flagi do zignorowaniaUnwise
. Będę musiał sprawdzić, co Rust lang (ponieważ jest budowany dla przeglądarki, jestem ciekawy, co robi) dla adresów URL. Jednak większość przeglądarek również z radością przekazuje „[”, „]”. Teoretycznie, tak jak powiedziałem w C / C ++, są sub / super, ale rzeczywistość nie jest tak prawdziwa. Jest wysoce zależny od interpretacji specyfikacji i semantyki super / podzbioru.Wszystkie prawidłowe znaki, które mogą być użyte w URI ( URL to typ URI ) są zdefiniowane w RFC 3986 .
Wszystkie pozostałe znaki mogą być użyte w adresie URL, pod warunkiem, że są one najpierw „zakodowane w adresie URL”. Obejmuje to zmianę nieprawidłowego znaku dla określonych „kodów” (zwykle w postaci symbolu procentu (%), po którym następuje liczba szesnastkowa).
Ten link, HTML Encoding Reference , zawiera listę kodowań nieprawidłowych znaków.
źródło
Kilka zakresów znaków Unicode jest prawidłowych HTML5 , chociaż ich użycie może nadal nie być dobrym pomysłem.
Np.
href
Doktorzy mówią : http://www.w3.org/TR/html5/links.html#attr-hyperlink-href :Następnie definicja „prawidłowego adresu URL” wskazuje na http://url.spec.whatwg.org/ , co oznacza, że jego celem jest:
Ten dokument definiuje punkty kodu URL jako:
Termin „punkty kodowe URL” jest następnie używany w instrukcji:
w kilku częściach algorytmu analizującego, w tym schemacie, autorytecie, ścieżce względnej, zapytaniu i stanach fragmentów: w zasadzie cały adres URL.
Ponadto walidator http://validator.w3.org/ podaje adresy URL podobne
"你好"
i nie przekazuje adresów URL zawierających znaki takie jak spacje"a b"
Oczywiście, jak wspomniał Stephen C, nie chodzi tylko o znaki, ale także o kontekst: musisz zrozumieć cały algorytm. Ale ponieważ klasa „Punkty kodu URL” jest używana w kluczowych punktach algorytmu, daje to dobre wyobrażenie o tym, czego możesz użyć, czy nie.
Zobacz także: Znaki Unicode w adresach URL
źródło
Muszę wybrać znak, aby podzielić adresy URL na ciąg, więc postanowiłem utworzyć listę znaków, których nie mogłem znaleźć w adresie URL:
Możliwe opcje to nowa linia, tabulacja, spacja, ukośnik odwrotny i
"<>{}^|
. Chyba pójdę ze spacją lub nową linią. :)źródło
Naprawdę nie jest to odpowiedź na twoje pytanie, ale sprawdzenie poprawności adresu URL to naprawdę poważna pita. Prawdopodobnie lepiej sprawdzić poprawność nazwy domeny i pozostaw część zapytania w adresie URL. To jest moje doświadczenie. Możesz również użyć polecenia ping do adresu URL i sprawdzić, czy spowoduje to prawidłową odpowiedź, ale może to być zbyt wiele jak na tak proste zadanie.
Wyrażenia regularne do wykrywania adresów URL są obfite, google :)
źródło
Wdrażam stary czytnik / pisarz zapytań i odpowiedzi http (0.9, 1.0, 1.1). Żądanie URI to najbardziej problematyczne miejsce.
Nie można tak po prostu używać RFC 1738, 2396 lub 3986. Istnieje wiele starych klientów HTTP i serwerów, które pozwalają na więcej znaków. Więc zrobiłem badania na podstawie przypadkowo opublikowane dzienniki dostępu webserver:
"GET URI HTTP/1.0" 200
.Odkryłem, że w URI często używane są następujące niestandardowe znaki:
Znaki te zostały opisane w RFC 1738 jako niebezpieczne .
Jeśli chcesz być zgodny ze wszystkimi starymi klientami i serwerami HTTP - musisz zezwolić tym znakom na żądanie URI.
Proszę przeczytać więcej informacji o tych badaniach w http-og .
źródło
Wymyśliłem kilka wyrażeń regularnych dla PHP, które konwertują adresy URL w tekście na tagi zakotwiczenia. (Najpierw konwertuje wszystkie adresy URL na http: //, a następnie konwertuje wszystkie adresy URL za pomocą https?: // na href = ... linki HTML
$string = preg_replace('/(https?:\/\/)([!#$&-;=?\-\[\]_a-z~%]+)/sim', '<a href="$1$2">$2</a>', preg_replace('/(\s)((www\.)([!#$&-;=?\-\[\]_a-z~%]+))/sim', '$1http://$2', $string) );
źródło