Welche Zeichen machen eine URL ungültig?
Sind das gültige URLs?
example.com/file[/].html
http://example.com/file[/].html
Welche Zeichen machen eine URL ungültig?
Sind das gültige URLs?
example.com/file[/].html
http://example.com/file[/].html
Antworten:
Im Allgemeinen können URIs gemäß RFC 3986 (siehe Abschnitt 2: Zeichen ) eines der folgenden 84 Zeichen enthalten:
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~:/?#[]@!$&'()*+,;=
Beachten Sie, dass in dieser Liste nicht angegeben ist, wo in der URI diese Zeichen vorkommen können.
Jedes andere Zeichen muss mit der Prozentcodierung ( %
hh
) codiert werden . Jeder Teil der URI unterliegt weiteren Einschränkungen hinsichtlich der Zeichen, die durch ein prozentual codiertes Wort dargestellt werden müssen.
/^([!#$&-;=?-[]_a-z~]|%[0-9a-fA-F]{2})+$/
Gab es noch etwas, das Sie hätten akzeptieren sollen? (Nur um klar zu sein, dieser reguläre Ausdruck prüft nur, ob die Zeichenfolge gültige URL-Zeichen enthält, nicht, ob die Zeichenfolge eine wohlgeformte URL enthält.)
Um einige Klarstellungen hinzuzufügen und die obige Frage direkt zu beantworten, gibt es mehrere Zeichenklassen, die Probleme für URLs und URIs verursachen.
Es gibt einige Zeichen, die nicht zulässig sind und niemals in einer URL / URI erscheinen sollten, reservierte Zeichen (siehe unten) und andere Zeichen, die in einigen Fällen Probleme verursachen können, aber als "unklug" oder "unsicher" gekennzeichnet sind. Erklärungen, warum die Zeichen eingeschränkt sind, sind in RFC-1738 (URLs) und RFC-2396 (URIs) klar formuliert. Beachten Sie, dass der neuere RFC-3986 (Aktualisierung auf RFC-1738) die Konstruktion definiert, welche Zeichen in einem bestimmten Kontext zulässig sind. Die ältere Spezifikation bietet jedoch eine einfachere und allgemeinere Beschreibung, welche Zeichen mit den folgenden Regeln nicht zulässig sind.
Ausgeschlossene US-ASCII-Zeichen, die in der URI-Syntax nicht zulässig sind:
control = <US-ASCII coded characters 00-1F and 7F hexadecimal>
space = <US-ASCII coded character 20 hexadecimal>
delims = "<" | ">" | "#" | "%" | <">
Das Zeichen "#" wird ausgeschlossen, da es verwendet wird, um einen URI von einer Fragmentkennung abzugrenzen. Das Prozentzeichen "%" wird ausgeschlossen, da es für die Codierung von Escapezeichen verwendet wird. Mit anderen Worten, "#" und "%" sind reservierte Zeichen, die in einem bestimmten Kontext verwendet werden müssen.
Eine Liste unkluger Zeichen ist zulässig, kann jedoch Probleme verursachen:
unwise = "{" | "}" | "|" | "\" | "^" | "[" | "]" | "`"
Zeichen, die innerhalb einer Abfragekomponente reserviert sind und / oder innerhalb einer URI / URL eine besondere Bedeutung haben:
reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | ","
Die obige "reservierte" Syntaxklasse bezieht sich auf diejenigen Zeichen, die in einem URI zulässig sind, in einer bestimmten Komponente der generischen URI-Syntax jedoch möglicherweise nicht zulässig sind. Zeichen im "reservierten" Satz sind nicht in allen Kontexten reserviert . Der Hostname kann beispielsweise einen optionalen Benutzernamen enthalten, sodass ftp://user@hostname/
das Zeichen '@' eine besondere Bedeutung haben kann.
Hier ist ein Beispiel für eine URL, die ungültige und unkluge Zeichen enthält (z. B. '$', '[', ']') und ordnungsgemäß codiert werden sollte:
http://mw1.google.com/mw-earth-vectordb/kml-samples/gp/seattle/gigapxl/$[level]/r$[y]_c$[x].jpg
Einige der Zeichenbeschränkungen für URIs / URLs hängen von der Programmiersprache ab. Zum Beispiel das '|' Das Zeichen (0x7C) wird, obwohl es in der URI-Spezifikation nur als "unklug" markiert ist, eine URISyntaxException im Java- Konstruktor java.net.URI auslösen, sodass eine URL wie http://api.google.com/q?exp=a|b
nicht zulässig ist und stattdessen so codiert werden muss, als http://api.google.com/q?exp=a%7Cb
würde Java mit einer URI-Objektinstanz verwendet.
?
ist gut in der Abfrage Abschnitt, aber nicht vor, und ich glaube nicht , @
in jedem dieser Listen gehört. Oh, und anstatt %25
in der letzten Saite, meinst du nicht %7C
?
Die meisten der hier vorhandenen Antworten sind unpraktisch, da sie die reale Verwendung von Adressen wie:
Zunächst ein Exkurs in die Terminologie. Was sind diese Adressen? Sind sie gültige URLs?
Historisch gesehen war die Antwort "nein". Laut RFC 3986 sind solche Adressen ab 2005 keine URIs (und daher keine URLs, da URLs eine Art von URIs sind ). Gemäß der Terminologie der IETF-Standards von 2005 sollten wir sie ordnungsgemäß als IRIs (Internationalized Resource Identifiers) gemäß RFC 3987 bezeichnen , die technisch gesehen keine URIs sind, sondern einfach durch prozentuale Codierung aller Nicht-ASCII-Zeichen in der IRI in URIs konvertiert werden können .
Laut moderner Spezifikation lautet die Antwort "Ja". Der WHATWG Living Standard klassifiziert einfach alles, was zuvor als "URIs" oder "IRIs" bezeichnet wurde, als "URLs". Dadurch wird die festgelegte Terminologie darauf abgestimmt, wie normale Personen, die die Spezifikation nicht gelesen haben, das Wort "URL" verwenden, was eines der Ziele der Spezifikation war .
Welche Zeichen sind gemäß dieser neueren Bedeutung von "URL" zulässig? In vielen Teilen der URL, wie z. B. der Abfragezeichenfolge und dem Pfad, dürfen beliebige "URL-Einheiten" verwendet werden
Was sind "URL-Codepunkte"?
Die URL-Codepunkte sind alphanumerisch ASCII, U + 0021 (!), U + 0024 ($), U + 0026 (&), U + 0027 ('), U + 0028 LINKE PARENTHESE, U + 0029 RECHTE PARENTHESE, U + 002A (*), U + 002B (+), U + 002C (,), U + 002D (-), U + 002E (.), U + 002F (/), U + 003A (:), U + 003B (;), U + 003D (=), U + 003F (?), U + 0040 (@), U + 005F (_), U + 007E (~) und Codepunkte im Bereich von U + 00A0 bis U. + 10FFFD, einschließlich, ohne Ersatz und Nicht-Zeichen.
(Beachten Sie, dass die Liste der "URL-Codepunkte" nicht enthalten ist %
, diese jedoch %
in "URL-Codeeinheiten" zulässig sind , wenn sie Teil einer Prozentcodierungssequenz sind.)
Der einzige Ort, an dem ich feststellen kann, wo die Spezifikation die Verwendung von Zeichen erlaubt, die nicht in diesem Satz enthalten sind, ist der Host , in dem IPv6-Adressen [
und ]
Zeichen enthalten sind. Überall sonst in der URL sind entweder URL-Einheiten oder noch restriktivere Zeichensätze zulässig.
Aus Gründen der Geschichte und da dies an anderer Stelle in den Antworten hier nicht vollständig untersucht wird, sollten wir untersuchen, ob dies unter den älteren Spezifikationen zulässig war.
Zunächst haben wir zwei Arten von reservierten RFC 3986- Zeichen :
:/?#[]@
, die Teil der generischen Syntax für einen in RFC 3986 definierten URI sind!$&'()*+,;=
, die nicht Teil der generischen Syntax des RFC sind, aber für die Verwendung als syntaktische Komponenten bestimmter URI-Schemata reserviert sind. Zum Beispiel sind Semikolons und Kommas als Teil der Syntax der verwendeten Daten URIs , und &
und =
als Teil des allgegenwärtigen verwendeten ?foo=bar&qux=baz
Format in Abfragezeichenfolgen (die nicht durch RFC 3986 spezifiziert).Jedes der oben genannten reservierten Zeichen kann legal in einer URI ohne Codierung verwendet werden, entweder um ihren syntaktischen Zweck zu erfüllen, oder nur als Literalzeichen in Daten an einigen Stellen, an denen eine solche Verwendung nicht als das Zeichen interpretiert werden kann, das seinem syntaktischen Zweck dient. (Obwohl /
eine URL eine syntaktische Bedeutung hat, können Sie sie in einer Abfragezeichenfolge nicht codiert verwenden, da sie in einer Abfragezeichenfolge keine Bedeutung hat.)
RFC 3986 spezifiziert auch einige nicht reservierte Zeichen, die immer einfach verwendet werden können, um Daten ohne Codierung darzustellen:
abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~
Schließlich ist das %
Zeichen selbst für Prozentcodierungen zulässig.
Damit bleiben nur die folgenden ASCII-Zeichen übrig, deren Anzeige in einer URL verboten ist :
"<>\^`{|}
Jedes andere Zeichen aus ASCII kann legal in einer URL enthalten sein.
Dann erweitert RFC 3987 diesen Satz nicht reservierter Zeichen um die folgenden Unicode-Zeichenbereiche:
%xA0-D7FF / %xF900-FDCF / %xFDF0-FFEF
/ %x10000-1FFFD / %x20000-2FFFD / %x30000-3FFFD
/ %x40000-4FFFD / %x50000-5FFFD / %x60000-6FFFD
/ %x70000-7FFFD / %x80000-8FFFD / %x90000-9FFFD
/ %xA0000-AFFFD / %xB0000-BFFFD / %xC0000-CFFFD
/ %xD0000-DFFFD / %xE1000-EFFFD
Diese Block - Auswahl aus dem alten spec scheint bizarr und willkürlich die neuesten Unicode gegebenen Blockdefinitionen ; Dies liegt wahrscheinlich daran, dass die Blöcke im Jahrzehnt seit dem Schreiben von RFC 3987 hinzugefügt wurden.
Schließlich ist es vielleicht erwähnenswert, dass es nicht ausreicht, nur zu wissen, welche Zeichen legal in einer URL erscheinen können, um zu erkennen, ob eine bestimmte Zeichenfolge eine legale URL ist oder nicht, da einige Zeichen nur in bestimmten Teilen der URL legal sind. Beispielsweise sind die reservierten Zeichen [
und ]
als Teil eines IPv6-Literal-Hosts in einer URL wie http: // [1080 :: 8: 800: 200C: 417A] / foo zulässig, in keinem anderen Kontext jedoch zulässig Das Beispiel von OP http://example.com/file[/].html
ist illegal.
In Ihrer Zusatzfrage haben Sie gefragt, ob www.example.com/file[/].html
es sich um eine gültige URL handelt.
Diese URL ist ungültig, da eine URL ein URI-Typ ist und ein gültiger URI ein Schema wie http:
(siehe RFC 3986 ) haben muss.
Wenn Sie fragen wollten, ob http://www.example.com/file[/].html
es sich um eine gültige URL handelt, lautet die Antwort immer noch Nein, da die eckigen Klammern dort nicht gültig sind.
Die eckigen Klammern sind für URLs in diesem Format reserviert: http://[2001:db8:85a3::8a2e:370:7334]/foo/bar
(dh ein IPv6-Literal anstelle eines Hostnamens)
Es lohnt sich, RFC 3986 sorgfältig zu lesen, wenn Sie das Problem vollständig verstehen möchten.
Unwise
URIs sehr ernst nehmen und dennoch gut mit URL-Bibliotheken umgehen können . Das heißt, es gibt keine Flagge, die ignoriert werden muss Unwise
. Ich muss herausfinden, was Rust lang (da es für einen Browser erstellt wird, bin ich gespannt, was es tut) für URLs. Die meisten Browser übergeben jedoch auch gerne "[", "]". Theoretisch sind sie, wie ich bereits sagte, mit C / C ++ sub / super, aber die Realität ist nicht so wahr. Es hängt stark von der Interpretation der Spezifikation und Semantik von Super / Subset ab.
Alle gültigen Zeichen, die in einem URI verwendet werden können (eine URL ist ein URI- Typ ), sind in RFC 3986 definiert .
Alle anderen Zeichen können in einer URL verwendet werden, sofern sie zuerst "URL-codiert" sind. Dies beinhaltet das Ändern des ungültigen Zeichens für bestimmte "Codes" (normalerweise in Form des Prozentzeichens (%) gefolgt von einer Hexadezimalzahl).
Dieser Link, HTML URL Encoding Reference , enthält eine Liste der Codierungen für ungültige Zeichen.
Einige der Unicode-Zeichenbereiche sind gültiges HTML5 , obwohl es möglicherweise immer noch keine gute Idee ist, sie zu verwenden.
ZB href
docs sagen http://www.w3.org/TR/html5/links.html#attr-hyperlink-href :
Das href-Attribut für a- und area-Elemente muss einen Wert haben, der eine gültige URL ist, die möglicherweise von Leerzeichen umgeben ist.
Dann verweist die Definition der "gültigen URL" auf http://url.spec.whatwg.org/ , was besagt , dass Folgendes angestrebt wird:
Richten Sie RFC 3986 und RFC 3987 an aktuellen Implementierungen aus und veralten Sie sie dabei.
Dieses Dokument definiert URL-Codepunkte als:
ASCII alphanumerisch, "!", "$", "&", "'", "(", ")", "*", "+", ",", "-", ".", "/" , ":", ";", "=", "?", "@", "_", "~" und Codepunkte in den Bereichen U + 00A0 bis U + D7FF, U + E000 bis U + FDCF , U + FDF0 bis U + FFFD, U + 10000 bis U + 1FFFD, U + 20000 bis U + 2FFFD, U + 30000 bis U + 3FFFD, U + 40000 bis U + 4FFFD, U + 50000 bis U + 5FFFD, U. +60000 bis U + 6FFFD, U + 70000 bis U + 7FFFD, U + 80000 bis U + 8FFFD, U + 90000 bis U + 9FFFD, U + A0000 bis U + AFFFD, U + B0000 bis U + BFFFD, U + C0000 zu U + CFFFD, U + D0000 zu U + DFFFD, U + E1000 zu U + EFFFD, U + F0000 zu U + FFFFD, U + 100000 zu U + 10FFFD.
Der Begriff "URL-Codepunkte" wird dann in der Anweisung verwendet:
Wenn c kein URL-Codepunkt und nicht "%" ist, analysieren Sie den Fehler.
in einigen Teilen des Parsing-Algorithmus, einschließlich des Schemas, der Berechtigung, des relativen Pfads, der Abfrage und der Fragmentzustände: also im Grunde die gesamte URL.
Der Validator http://validator.w3.org/ gilt auch für URLs wie "你好"
und nicht für URLs mit Zeichen wie Leerzeichen"a b"
Natürlich geht es, wie von Stephen C erwähnt, nicht nur um Zeichen, sondern auch um den Kontext: Sie müssen den gesamten Algorithmus verstehen. Da jedoch die Klasse "URL-Codepunkte" für wichtige Punkte des Algorithmus verwendet wird, gibt sie eine gute Vorstellung davon, was Sie verwenden können oder nicht.
Siehe auch: Unicode-Zeichen in URLs
Ich muss Zeichen auswählen, um URLs in Zeichenfolgen aufzuteilen, daher habe ich beschlossen, eine Liste von Zeichen zu erstellen, die von mir selbst nicht in der URL gefunden werden konnten:
>>> allowed = "-_.~!*'();:@&=+$,/?%#[]?@ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
>>> from string import printable
>>> ''.join(set(printable).difference(set(allowed)))
'`" <\x0b\n\r\x0c\\\t{^}|>'
Die möglichen Auswahlmöglichkeiten sind also Zeilenumbruch, Tabulator, Leerzeichen, Backslash und "<>{}^|
. Ich denke, ich werde mit dem Leerzeichen oder der Newline gehen. :) :)
Nicht wirklich eine Antwort auf Ihre Frage, aber das Überprüfen von URLs ist wirklich eine ernsthafte Pita. Sie sind wahrscheinlich besser dran, den Domainnamen zu überprüfen und den Abfrageteil der URL zu belassen. Das ist meine Erfahrung. Sie können auch die URL anpingen und prüfen, ob eine gültige Antwort vorliegt. Dies ist jedoch möglicherweise zu viel für eine so einfache Aufgabe.
Reguläre Ausdrücke zum Erkennen von URLs sind reichlich vorhanden, google it :)
Ich implementiere alte http (0.9, 1.0, 1.1) Anforderungs- und Antwortleser / -schreiber. Anforderungs-URI ist der problematischste Ort.
Sie können RFC 1738, 2396 oder 3986 nicht einfach so verwenden, wie es ist. Es gibt viele alte HTTP-Clients und -Server, die mehr Zeichen zulassen. Daher habe ich anhand versehentlich veröffentlichter Webserver-Zugriffsprotokolle Nachforschungen angestellt : "GET URI HTTP/1.0" 200
.
Ich habe festgestellt, dass die folgenden nicht standardmäßigen Zeichen in URI häufig verwendet werden:
\ { } < > | ` ^ "
Diese Zeichen wurden in RFC 1738 als unsicher beschrieben .
Wenn Sie mit allen alten HTTP-Clients und -Servern kompatibel sein möchten, müssen Sie diese Zeichen im Anforderungs-URI zulassen .
Weitere Informationen zu dieser Forschung finden Sie unter http-og .
Ich habe mir ein paar reguläre Ausdrücke für PHP ausgedacht, die URLs in Text in Ankertags konvertieren. (Zuerst werden alle www. URLs in http: // konvertiert, dann werden alle URLs mit https ?: // in einen href = ... html-Link konvertiert
$string = preg_replace('/(https?:\/\/)([!#$&-;=?\-\[\]_a-z~%]+)/sim', '<a href="$1$2">$2</a>',
preg_replace('/(\s)((www\.)([!#$&-;=?\-\[\]_a-z~%]+))/sim', '$1http://$2', $string)
);