Sichere Zeichen für freundliche URL [geschlossen]

168

Ich muss eine Website erstellen, die Artikel enthält, und ich möchte dafür freundliche URLs erstellen, beispielsweise die URL der Seite mit

Titel: Artikeltest

sollte werden : http://www.example.com/articles/article_test.

Natürlich muss ich einige Zeichen wie ?oder aus dem Titel entfernen #, aber ich bin mir nicht sicher, welche ich entfernen soll.

Kann mir jemand sagen, welche Charaktere sicher aufbewahrt werden können?

Paulo
quelle
Es gab eine ähnliche Frage, hier . Probieren Sie es aus, vielleicht finden Sie dort auch einige nützliche Antworten (es gab ziemlich viele davon).
Turm

Antworten:

210

So zitieren Sie Abschnitt 2.3 von RFC 3986 :

"Zeichen, die in einer URI zulässig sind, aber keinen reservierten Zweck haben, werden als nicht reserviert bezeichnet. Dazu gehören Groß- und Kleinbuchstaben, Dezimalstellen, Bindestrich, Punkt, Unterstrich und Tilde."

ALPHA  DIGIT  "-" / "." / "_" / "~"

Beachten Sie, dass RFC 3986 weniger reservierte Satzzeichen enthält als der ältere RFC 2396 .

Kopf überspringen
quelle
@Skip Head, enthalten "Zeichen" lateinisch codierte Zeichen wie çund õ?
Mohamad
6
@ Mohamad: Nein, nur ASCII, obwohl die UTF-8-Unterstützung immer besser wird.
Dietrich Epp
@Dietrich Epp, danke. Ich denke, es sollte keine Rolle spielen, ob die URL für Dekorations- und SEO-Zwecke ist, wie: www.mysite.com/[postId‹/post-title-with-ç-and-õ
Mohamad
1
@Mohamad: Der letzte Teil dort wird unter der Haube geändert post-title-with-%C3%A7-and-%C3%B5, wird aber weiterhin in der Positionsleiste des Benutzers als angezeigt post-title-with-ç-and-õ.
Dietrich Epp
7
Ihre Leser sind Portugiesen, verwenden Sie also portugiesische Zeichen.
Dietrich Epp
107

Es gibt zwei Zeichensätze, auf die Sie achten müssen: reserviert und unsicher .

Die reservierten Zeichen sind:

  • Et-Zeichen ("&")
  • Dollar ("$")
  • Pluszeichen ("+")
  • Komma (",")
  • Schrägstrich ("/")
  • Doppelpunkt (":")
  • Semikolon (";")
  • gleich ("=")
  • Fragezeichen ("?")
  • Symbol 'At' ("@")
  • Pfund ("#").

Die allgemein als unsicher geltenden Zeichen sind:

  • Platz (" ")
  • kleiner als und größer als ("<>")
  • Klammern öffnen und schließen ("[]")
  • Klammern öffnen und schließen ("{}")
  • Rohr ("|")
  • Backslash ("\")
  • Caret ("^")
  • Prozent ("%")

Möglicherweise habe ich eine oder mehrere vergessen, was dazu führt, dass ich die Antwort von Carl V wiederhole. Auf lange Sicht ist es wahrscheinlich besser, eine "weiße Liste" zulässiger Zeichen zu verwenden und dann die Zeichenfolge zu codieren, als zu versuchen, mit Zeichen Schritt zu halten, die von Servern und Systemen nicht zugelassen werden.

Gary.Ray
quelle
#ist ein reserviertes Zeichen, das für Lesezeichen auf einer bestimmten Seite verwendet wird und aus einem HTML-Element mit einem übereinstimmenden #Namensattribut oder ID-Attribut (sans -symbol) besteht.
TheLonelyGhost
Danke - ich habe die Antwort aktualisiert.
Gary.Ray
Das Fragezeichen wird hier sowohl als reserviert als auch als unsicher angezeigt - ich halte es für nur reserviert, aber ich kann mich irren
Jonathan Basile
6
Andere scheinen nicht der Meinung zu sein, dass die Tilde ~unsicher ist. Bist du sicher, dass es so ist?
Dr.
3
Die Whitelist ist nicht so gut, wenn Sie mit anderen Sprachen als Englisch umgehen. Unicode hat einfach zu viele OK-Codepunkte. Daher ist es wahrscheinlich am einfachsten, die unsicheren auf die schwarze Liste zu setzen, um sie in regulären Ausdrücken zu implementieren.
Patanjali
41

Am besten behalten Sie nur einige Zeichen (Whitelist), anstatt bestimmte Zeichen (Blacklist) zu entfernen.

Sie können jedes Zeichen technisch zulassen, solange Sie es ordnungsgemäß codieren. Um im Geiste der Frage zu antworten, sollten Sie jedoch nur die folgenden Zeichen zulassen:

  1. Kleinbuchstaben (Großbuchstaben in Kleinbuchstaben umwandeln)
  2. Zahlen 0 bis 9
  3. Ein Bindestrich - oder Unterstrich _
  4. Tilde ~

Alles andere hat eine möglicherweise besondere Bedeutung. Zum Beispiel könnten Sie denken, Sie könnten + verwenden, aber es kann durch ein Leerzeichen ersetzt werden. & ist auch gefährlich, insbesondere wenn einige Umschreiberegeln verwendet werden.

Lesen Sie wie bei den anderen Kommentaren die Standards und Spezifikationen für vollständige Details.

Carl
quelle
15
Ein Preiod, den ich heute entdeckt habe, ist eine schlechte Wahl für einen URL-sicheren Base64-Encoder, da es in seltenen Fällen vorkommen kann, dass Ihre codierten Daten zwei aufeinanderfolgende Punkte ("..") erzeugen, was für dass es sich auf das übergeordnete Verzeichnis bezieht.
Pohl
5
@pohl: Dies ist nur dann ein Problem, wenn Ihre URL als Dateipfad verwendet wird, entweder in Ihrem Code oder wenn Ihr Webserver tatsächlich versucht, die URL Dateien zuzuordnen, bevor die Anforderung an ein Skript weitergeleitet wird (leider sehr häufig).
André Caron
4
In unserem Fall wäre es in Ordnung, es als Dateipfad zu verwenden, da Dateien unter Unix mehrere und sogar aufeinanderfolgende Punkte in ihren Namen haben dürfen. Für uns trat das Problem in einem Überwachungstool namens Site Scope auf, das einen Fehler (möglicherweise einen naiven regulären Ausdruck) aufweist und falsche falsche Ausfallzeiten meldet. Für uns stecken wir in einer alten Version von Site Scope fest, das Admin-Team weigert sich, für ein Upgrade zu bezahlen, und ein sehr wichtiger Kunde hat Site Scope (nicht gleichwertig) in seinen Vertrag aufgenommen. Zugegeben, die meisten werden sich nicht in meinen Schuhen befinden.
Pohl
8
Gott sei Dank, dass jemand eine Liste gepostet hat, ohne viel zu plappern. Wie für Punkt (.) - wie @pohl sagte, verwenden Sie es nicht! Hier ist ein weiterer seltsamer Fall in IIS (ich weiß nicht, ob dies auf anderen Webservern geschieht): Wenn er sich am Ende Ihrer URL befindet, wird höchstwahrscheinlich ein 404-Fehler angezeigt (es wird versucht, nach [/ pagename] zu suchen]. Seite)
nikib3ro
34

Immer sicher

Diese sind sicher (in Theorie / Spezifikation), im Grunde überall außer dem Domainnamen.
Prozentcodieren Sie alles, was nicht aufgeführt ist, und Sie können loslegen.

    A-Z a-z 0-9 - . _ ~ ( ) ' ! * : @ , ;

Manchmal sicher

Nur sicher, wenn innerhalb bestimmter URL-Komponenten verwendet; Vorsichtig verwenden.

    Paths:     + & =
    Queries:   ? /
    Fragments: ? / # + & =
    

Niemals sicher

Gemäß der URI-Spezifikation (RFC 3986) müssen alle anderen Zeichen prozentual codiert sein. Das beinhaltet:

    <space> <control-characters> <extended-ascii> <unicode>
    % < > [ ] { } | \ ^
    

Wenn maximale Kompatibilität ein Problem darstellt, beschränken Sie den Zeichensatz auf AZ az 0-9 - _.
(mit Punkten nur für Dateinamenerweiterungen).

Denken Sie an den Kontext

Selbst wenn eine URL pro Spezifikation gültig ist, kann sie je nach Kontext dennoch "unsicher" sein. Beispiel: Eine Datei: /// URL mit ungültigen Dateinamenzeichen oder eine Abfragekomponente mit "?", "=" Und "&", wenn sie nicht als Trennzeichen verwendet werden. Die korrekte Behandlung dieser Fälle hängt im Allgemeinen von Ihren Skripten ab und kann umgangen werden. Beachten Sie dies jedoch.

Beejor
quelle
Könnten Sie Quellen für Ihren zweiten Anspruch angeben ("Manchmal sicher")? Insbesondere glaube ich, dass Sie zu Unrecht sagen, dass =dies für Anfragen nicht sicher ist. Beispielsweise akzeptiert FIQL Gleichheitszeichen und beschreibt sich selbst als "URI-freundlich" und "optimiert und für die Verwendung in der Abfragekomponente vorgesehen". In meiner Interpretation erlaubt RFC 3986 explizit "=", "&", "+" und andere in Abfragen.
DanielM
@DanielM "?", "=" Und "&" sind in Abfragen pro Spezifikation gültig, obwohl sie in der Praxis häufig zum Parsen von Name-Wert-Paaren innerhalb der Abfrage verwendet werden. Daher können sie als Teil der Namen / Werte selbst unsicher sein. Ob dies "unsicher" ist oder nicht, kann Ansichtssache sein.
Beejor
Einige Quellen, wie gewünscht. (1) RFC 3986, Abschnitt 3.4: "[...] Abfragekomponenten werden häufig verwendet, um identifizierende Informationen in Form von [...] Schlüssel-Wert-Paaren zu übertragen." (2) WhatWG URL Spec, Sec. 6.2: "Das Erstellen und Stringifizieren eines URLSearchParams-Objekts ist ziemlich einfach: [...]params.toString() // "key=730d67" " (3) PHP-Handbuch, http-build-query: "Generieren Sie eine URL-codierte Abfragezeichenfolge. [...] Das obige Beispiel gibt Folgendes aus: 0=foo&1=bar[...]"(4) J. Starr, Perishable Press:" Beim Erstellen von Webseiten ist es häufig erforderlich, Links hinzuzufügen, für die parametrisierte Abfragezeichenfolgen erforderlich sind. "
Beejor
@Beejor: Ich erstelle eine URL und verwende '-' und ';' während der Konstruktion. Es ist keine Web-App, sondern eine mobile App. Kein Webentwickler und wäre ich daher sicher, wenn ich die beiden oben genannten Zeichen in der Path-Eigenschaft verwenden würde? docs.microsoft.com/en-us/dotnet/api/…
karsnen
1
@karsnen Das sind gültige URL-Zeichen. Beachten Sie jedoch, dass einige Systeme bestimmte Zeichen in Dateinamen nicht zulassen, wenn sie zum Verweisen auf Pfade in einem lokalen Dateisystem verwendet werden. Beispielsweise wäre "file: /// path / to / my: file.ext" auf einem Mac ungültig.
Beejor
17

Mit Blick auf RFC3986 - Uniform Resource Identifier (URI): Generische Syntax dreht sich Ihre Frage um die Pfadkomponente eines URI.

    foo://example.com:8042/over/there?name=ferret#nose
     \_/   \______________/\_________/ \_________/ \__/
      |           |            |            |        |
   scheme     authority       path        query   fragment
      |   _____________________|__
     / \ /                        \
     urn:example:animal:ferret:nose

Unter Berufung auf Abschnitt 3.3 sind gültige Zeichen für einen URI segmentvom Typ pchar:

pchar = nicht reserviert / pct-codiert / sub-delims / ":" / "@"

Was zerfällt zu:

ALPHA / DIGIT / "-" / "." / "_" / "~"

pct-encoded

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

":" / "@"

Oder mit anderen Worten: Sie können verwenden eine beliebige (nicht-Steuerungen) Zeichen aus dem ASCII - Tabelle , ausnehmen / , ?, #, [und ].

Dieses Verständnis wird durch RFC1738 - Uniform Resource Locators (URL) unterstützt .

Philzen
quelle
2
Dies ist ein großartiges Beispiel für eine theoretisch korrekte Antwort, die zu Problemen führt, wenn sie auf die reale Welt angewendet wird, in der wir tatsächlich leben. Es ist wahr, dass die meisten dieser Charaktere die meiste Zeit kein Problem verursachen. In der realen Welt gibt es jedoch Dinge wie Proxys, Router, Gateways, Relays usw., die es "lieben", URLs auf eine Weise zu überprüfen und mit ihnen zu interagieren, die den theoretischen Standard missachtet. Um diese Fallstricke zu vermeiden, können Sie sich nur auf Alphanumerik, Bindestrich, Unterstrich und Punkt beschränken.
Deltamind106
1
@ deltamind106 Können Sie Beispiele und / oder Referenzen angeben, um zu verdeutlichen, welche dieser Zeichen gemäß den RFCs tatsächlich nicht sicher sind? Ich würde es vorziehen, mich an die Fakten zu halten, die in meiner Antwort durch Standards gestützt werden, und ich freue mich, meine Antwort zu aktualisieren, wenn Sie Fakten identifizieren können, die ich möglicherweise vernachlässigt habe.
Philzen
2
@ deltamind106 Ich würde vorschlagen, dass wir versuchen, Produkte dazu zu bringen, den Standards zu entsprechen, anstatt Entwicklern zu sagen, dass sie dies nicht tun sollen. Ich halte Ihre Warnung für verdient, aber wir sollten unseren Teil dazu beitragen, den Anbietern bei Bedarf Verstöße zu melden.
Lo-Tan
@Philzen: Ich erstelle eine URL und verwende '-' und ';' während der Konstruktion. Es ist keine Web-App, sondern eine mobile App. Kein Webentwickler und wäre ich daher sicher, wenn ich die beiden oben genannten Zeichen in der Path-Eigenschaft verwenden würde? docs.microsoft.com/en-us/dotnet/api/…
karsnen
1
@karsnen Ja natürlich -und ;sicher, das ist meine Antwort und RFC klar.
Philzen
12

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

LKK
quelle
3
Bedeutet "ALPHA" nicht "DIGIT"? Ich gehe davon aus, dass ALPHA für "alphanumerisch" steht und alphanumerisch Groß-, Klein- und Ziffern bedeutet.
Luc
11
Eigentlich bedeutet Alpha nicht alphanumerisch. Alpha und Numerisch sind zwei verschiedene Dinge und Alphanumerisch ist die Kombination dieser Dinge. Er hätte seine Antwort so schreiben können: ALPHANUMERIC / "-" / "." / "_" / "~"
MacroMan
1
Die ABNF-Notation für "nicht reserviert" in RFC 3986 listet sie separat auf.
Patanjali
11

Aus dem von Ihnen beschriebenen Kontext vermute ich, dass das, was Sie tatsächlich versuchen, als "SEO-Slug" bezeichnet wird. Die allgemein bekannteste Praxis für diese ist:

  1. In Kleinbuchstaben konvertieren
  2. Konvertieren Sie ganze Zeichenfolgen außer az und 0-9 in einen Bindestrich (-) (keine Unterstriche).
  3. Entfernen Sie 'Stoppwörter' aus der URL, dh nicht sinnvoll indizierbare Wörter wie 'a', 'an' und 'the'. Google 'Stoppwörter' für umfangreiche Listen

Als Beispiel würde ein Artikel mit dem Titel "Die Verwendung von! @% $ * Zur Darstellung des Fluchens in Comics" eine Menge "Verwendung, die das Fluchen von Comics darstellt" erhalten.

Chaos
quelle
Ist es wirklich ein guter Ansatz, diese "Stoppwörter" aus der URL zu entfernen? Würden Suchmaschinen eine Website deswegen bestrafen?
Paulo
Es wird allgemein angenommen, dass Suchmaschinen nur einen Teil der URL anerkennen und / oder späteren Teilen eine geringere Bedeutung beimessen. Wenn Sie also Stoppwörter entfernen, maximieren Sie die Anzahl der Keywords, die Sie in Ihre URL einbetten, und haben eine Chance von tatsächlich Rang auf.
Chaos
1
@chaos Empfehlen Sie immer noch, StopWord zu entfernen, wenn Sie dies berücksichtigen: seobythesea.com/2008/08/google-stopword-patent Können Sie auch eine gute Liste von Stoppwörtern empfehlen? Dies ist die beste Liste, die ich bisher gefunden habe - link-assistant.com/seo-stop-words.html
nikib3ro
@ kape123 Das sieht für mich nicht nach einer sehr guten Liste aus. "c" und "d" sind Programmiersprachen, und viele dieser anderen Wörter sehen ebenfalls bedeutsam aus. Ich würde wahrscheinlich nur die grundlegenden entfernen: a, und, ist, auf, von oder, mit.
Mpen
6

Das Format für einen URI ist in RFC 3986 definiert . Siehe Abschnitt 3.3 für Details.

Joschi
quelle
6

Aus SEO-Sicht werden Bindestriche Unterstrichen vorgezogen. In Kleinbuchstaben konvertieren, alle Apostrophe entfernen und dann alle nicht alphanumerischen Zeichenfolgen durch einen einzigen Bindestrich ersetzen. Schneiden Sie überschüssige Bindestriche von Anfang und Ende ab.

mpen
quelle
3

Ich hatte ein ähnliches Problem, wollte hübsche URLs haben und kam zu dem Schluss, dass ich nur Buchstaben, Ziffern und _ in URLs zulassen muss. Das ist in Ordnung, dann habe ich einen schönen regulären Ausdruck geschrieben und festgestellt, dass alle UTF8-Zeichen keine Buchstaben in .NET sind und verschraubt wurden. Dies scheint ein bekanntes Problem für die .NET-Regex-Engine zu sein. Also bin ich zu dieser Lösung gekommen:

private static string GetTitleForUrlDisplay(string title)
{
    if (!string.IsNullOrEmpty(title))
    {
        return Regex.Replace(Regex.Replace(title, @"[^A-Za-z0-9_-]", new MatchEvaluator(CharacterTester)).Replace(' ', '-').TrimStart('-').TrimEnd('-'), "[-]+", "-").ToLower();
    }
    return string.Empty;
}


/// <summary>
/// All characters that do not match the patter, will get to this method, i.e. useful for unicode chars, because
/// .NET impl of regext do not handle unicode chars. So we use char.IsLetterOrDigit() which works nicely and we 
/// return what we approve and return - for everything else.
/// </summary>
/// <param name="m"></param>
/// <returns></returns>
private static string CharacterTester(Match m)
{
    string x = m.ToString();
    if (x.Length > 0 && char.IsLetterOrDigit(x[0]))
    {
        return x.ToLower();
    }
    else
    {
        return "-";
    }
}
Lubomir Toshev
quelle
3
.NET-Regexe unterstützen Unicode eigentlich recht gut. Sie müssen für alle Buchstaben Unicode-Zeichenklassen verwenden, z. B. \ p {L}. Siehe msdn.microsoft.com/en-us/library/20bw873z.aspx#CategoryOrBlock
TheCycoONE
1

Ich fand es sehr nützlich, meine URL in eine sichere zu verschlüsseln, als ich einen Wert über ajax / php an eine URL zurückgab, die dann erneut von der Seite gelesen wurde.

PHP-Ausgabe mit URL-Encoder für das Sonderzeichen &

//PHP returning the sucess info of ajax request
echo "".str_replace('&','%26',$_POST['name'])." category was changed";

//javascript sending the value to url
window.location.href='time.php?return=updated&val='+msg;

//javascript/php executing the function printing the value of the url,
//now with the text normally lost in space because of the reserved & character.

setTimeout("infoApp('updated','<?php echo $_GET['val'];?>');",360);

Hoffe, jemand findet meine kleinen Code-Auszüge nützlich! :) :)

DIY-Forum
quelle
0

Ich denke, Sie suchen nach etwas wie "URL-Codierung" - Codierung einer URL, damit sie im Web "sicher" verwendet werden kann:

Hier ist eine Referenz dafür. Wenn Sie keine Sonderzeichen möchten, entfernen Sie einfach alle Zeichen, für die eine URL-Codierung erforderlich ist:

http://www.w3schools.com/TAGS/ref_urlencode.asp

Andy White
quelle
-4

Zwischen 3-50 Zeichen. Kann Kleinbuchstaben, Zahlen und Sonderzeichen enthalten - Punkt (.), Bindestrich (-), Unterstrich (_) und mit der Rate (@).

Ramji
quelle
4
Irgendeine Referenz dafür?
Dakab