In einer URL zulässige Zeichen

190

Kennt jemand die vollständige Liste der Zeichen, die in einem GET verwendet werden können, ohne codiert zu werden? Im Moment benutze ich AZ az und 0-9 ... aber ich suche nach der vollständigen Liste.

Ich bin auch daran interessiert, ob es eine Spezifikation für die bevorstehende Hinzufügung von chinesischen, arabischen URLs gibt (da dies offensichtlich einen großen Einfluss auf meine Frage haben wird).

Kennzeichen
quelle
5
Die in einer URI zulässigen Zeichen sind entweder reserviert !*'();:@&=+$,/?#[]oder nicht reserviert A-Za-z0-9_.~-(oder ein Prozentzeichen %als Teil einer Prozentcodierung)
Mikl
1
In MySQL verwende ich dies REGEXP '[^]A-Za-z0-9_.~!*''();:@&=+$,/?#[%-]+', um eine URL-Zeichenfolge mit schlechten Zeichen zu finden. Vielleicht ist es auch für jemand anderen nützlich.
Mikl
@Mikl: Das Ding sieht kaum wie ein regulärer Ausdruck aus.
Jens Mander

Antworten:

180

Aus der RFC 1738- Spezifikation:

Daher dürfen nur alphanumerische Zeichen, die Sonderzeichen " $-_.+!*'()," und reservierte Zeichen, die für ihre reservierten Zwecke verwendet werden, innerhalb einer URL nicht codiert verwendet werden.

EDIT: Wie @Jukka K. Korpela richtig hervorhebt, wurde dieser RFC von RFC 3986 aktualisiert . Dies hat die für den Host gültigen Zeichen erweitert und verdeutlicht. Leider ist es nicht einfach zu kopieren und einzufügen, aber ich werde mein Bestes geben.

In der ersten übereinstimmenden Reihenfolge:

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
Myles
quelle
5
@ Tim Slash ist ein reserviertes Zeichen. Wenn es für seinen reservierten Zweck verwendet wird (Abgrenzung von Pfaden, Protokollabgrenzung ...), muss es nicht maskiert werden. Ansonsten ist es so.
Myles
4
Generische Syntaxregeln von RFC 1738 wurden 1998 überholt.
Jukka K. Korpela
3
@Myles, STD 66 (= RFC 3986) wird in anderen Antworten erwähnt. Ob der Inhalt der Antworten korrekt ist, ist eine andere Frage. Ich denke, keine der Antworten beschreibt die vollständige Liste richtig.
Jukka K. Korpela
4
Und Sie können A-Za-z0-9_.-~am Anfang dieser Antwort eine Liste nicht reservierter und reservierter Zeichen hinzufügen . !*'();:@&=+$,/?#[]Es kann Zeit für Menschen sparen
Mikl
2
@basZero Es tut mir leid, dass Sie es verwirrend fanden, aber die vollständige Antwort ist nicht einfach. Die Antwort auf Ihre Frage ist nein, da es sich um ein reserviertes Zeichen handelt, wie angegeben von:reserved = gen-delims / sub-delims gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@"
Myles
42

Die in einer URI zulässigen Zeichen sind entweder reserviert oder nicht reserviert (oder ein Prozentzeichen als Teil einer Prozentcodierung).

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

Dies sind nicht reservierte RFC 3986- Zeichen (Abschnitt 2.3) sowie reservierte Zeichen (Abschnitt 2.2), wenn sie ihre besondere Bedeutung behalten müssen. Und auch ein Prozentzeichen als Teil einer Prozentcodierung.

Bernstein
quelle
7
Während dieser Link die Frage beantworten kann, ist es besser, die wesentlichen Teile der Antwort hier aufzunehmen und den Link als Referenz bereitzustellen. Nur-Link-Antworten können ungültig werden, wenn sich die verknüpfte Seite ändert.
Jaestevan
@jaestevan Zitat aus dem verlinkten Dokument:The characters allowed in a URI are either reserved or unreserved (or a percent character as part of a percent-encoding)
Mikl
26

Die vollständige Liste der 66 nicht reservierten Zeichen finden Sie in RFC3986 hier: http://tools.ietf.org/html/rfc3986#section-2.3

Dies ist ein beliebiges Zeichen im folgenden regulären Ausdruckssatz:

[A-Za-z0-9_.\-~]
Slacy
quelle
2
Sie können diese auch reserviert verwenden.
Qwerty
Der veraltete RFC1738 ist gelistet {}^\~und backtickals unsicher eingestuft. Und RFC3986 listet \ aufgrund des Dateisystems als unsicher auf. Dies bedeutet, {}^dass auch verwendet werden könnte.
mgutt
Wenn Sie also beispielsweise versuchen, das Ende einer URL innerhalb einer Zeichenfolge zu finden (was ich bin), sollten Sie sich in der akzeptierten Antwort an die veralteten Standards halten ... Wenn Sie URLs validieren , sollten Sie dies tun Verwenden Sie den Zeichensatz für diese Antwort.
Ashleedawg
Achtung, Sie haben dies als Zeichenklasse für reguläre Ausdrücke geschrieben. Stellen Sie sicher, -dass Sie der Zeichenklasse entkommen oder sie am Anfang oder Ende der Zeichenklasse [.-~]
einfügen
19

Ich habe es getestet, indem ich meine Website (Apache) mit allen verfügbaren Zeichen auf meiner deutschen Tastatur als URL-Parameter angefordert habe:

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

Diese wurden nicht verschlüsselt:

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

Nicht verschlüsselt nach urlencode():

0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.-_

Nicht verschlüsselt nach rawurlencode():

0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.-_~

Hinweis: Vor PHP 5.3.0 wegen RFC 1738rawurlencode() codiert . Dies wurde jedoch durch RFC 3986 ersetzt, sodass es jetzt sicher verwendet werden kann. Aber ich verstehe nicht, warum zum Beispiel durch codiert werden, weil sie in RFC 3986 nicht erwähnt werden.~{}rawurlencode()

Ein zusätzlicher Test, den ich durchgeführt habe, betraf die automatische Verknüpfung in Mail-Texten. Ich habe Mozilla Thunderbird, aol.com, Outlook.com, Gmail.com, gmx.de und yahoo.de getestet und sie haben URLs mit diesen Zeichen vollständig verknüpft:

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

Natürlich ?war das auch verlinkt, aber nur wenn es einmal benutzt wurde.

Einige Leute würden jetzt vorschlagen, nur die rawurlencode()Zeichen zu verwenden, aber haben Sie jemals gehört, dass jemand Probleme beim Öffnen dieser Websites hatte?

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

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

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

Am Zeichen, Doppelpunkt, Komma und Ausrufezeichen
https: //www.google.com/maps/place/USA/@36.2218457, ...

Aus diesem Grund sollten diese Zeichen ohne Probleme unverschlüsselt verwendet werden können. Natürlich sollten Sie &;wegen Codierungssequenzen wie nicht verwenden &amp;. Es gilt der gleiche Grund wie für %die Codierung von Zeichen im Allgemeinen. Und =da es einem Parameternamen einen Wert zuweist.

Schließlich würde ich sagen, dass es in Ordnung ist, diese nicht codierten zu verwenden:

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

Wenn Sie jedoch zufällig generierte URLs erwarten, sollten Sie diese nicht verwenden .!, da diese das Ende eines Satzes markieren und einige E-Mail-Apps das letzte Zeichen der URL nicht automatisch verknüpfen. Beispiel:

Visit http://example.com/foo=bar! !
mgutt
quelle
Praktischer Ansatz - gute Arbeit. War auf der Suche nach Ihrer letzten Liste - das +Zeichen vor allem :-D
Oliver
12

Von hier aus

Daher dürfen nur alphanumerische Zeichen, Sonderzeichen $-_.+!*'(), und reservierte Zeichen, die für ihre reservierten Zwecke verwendet werden, innerhalb einer URL unverschlüsselt verwendet werden.

AdaTheDev
quelle
5

RFC3986 definiert zwei Zeichensätze, die Sie in einem URI verwenden können:

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

    reserviert = Gen-Delims / Sub-Delims

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

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

    Der Zweck reservierter Zeichen besteht darin, eine Reihe von Begrenzungszeichen bereitzustellen, die von anderen Daten innerhalb eines URI unterscheidbar sind. URIs, die sich in der Ersetzung eines reservierten Zeichens durch das entsprechende prozentual codierte Oktett unterscheiden, sind nicht äquivalent.

  • Nicht reservierte Charaktere :A-Za-z0-9-_.~

    nicht reserviert = ALPHA / DIGIT / "-" / "." / "_" / "~"

    Zeichen, die in einer URI zulässig sind, aber keinen reservierten Zweck haben, werden als nicht reserviert bezeichnet.

Cyker
quelle
3

Die bevorstehende Änderung gilt für chinesische, arabische Domainnamen und nicht für URIs. Die internationalisierten URIs werden als IRIs bezeichnet und sind in RFC 3987 definiert . Allerdings würde ich empfehlen, dies nicht selbst zu tun, sondern sich auf eine vorhandene, getestete Bibliothek zu verlassen, da es viele Möglichkeiten für die URI-Codierung / -Decodierung gibt und was nach Spezifikation als sicher angesehen wird, im Vergleich zu dem, was bei tatsächlicher Verwendung sicher ist (Browser). .

dajobe
quelle
0

Wenn Sie den Benutzern eine besondere Erfahrung bieten möchten, können Sie pushStateeine Vielzahl von Zeichen in die URL des Browsers einfügen:

Geben Sie hier die Bildbeschreibung ein

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);
Grimmig
quelle