Personaggi sicuri per URL amichevole [chiuso]


168

Devo creare un sito Web che contenga articoli e vorrei creare URL amichevoli per esso, ad esempio l'URL della pagina con

Titolo: Articolo Test

dovrebbe diventare: http://www.example.com/articles/article_test.

Ovviamente devo rimuovere alcuni personaggi dal titolo come ?o #, ma non sono sicuro di quali rimuovere.

Qualcuno può dirmi quali personaggi sono sicuri da conservare?


C'era una domanda simile, qui . Dai un'occhiata, potresti trovare alcune risposte utili anche lì (ce n'erano molte).
Rook,

Risposte:


210

Per citare la sezione 2.3 di RFC 3986 :

"I caratteri consentiti in un URI ma che non hanno uno scopo riservato sono chiamati senza prenotazione. Questi includono lettere maiuscole e minuscole, cifre decimali, trattino, punto, trattino basso e tilde."

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

Si noti che RFC 3986 elenca meno segni di punteggiatura riservati rispetto al precedente RFC 2396 .


@Skip Head, i "personaggi" includono caratteri codificati in latino come çe õ?
Mohamad,

6
@Mohamad: No, solo ASCII, anche se il supporto UTF-8 sta migliorando.
Dietrich Epp,

@Dietrich Epp, grazie. Immagino che non dovrebbe importare se l'URL è per scopi decorativi e SEO, come: www.mysite.com/[postId[/post-title-with-ç-and-õ
Mohamad,

1
@Mohamad: l'ultima parte verrà cambiata sotto il cofano post-title-with-%C3%A7-and-%C3%B5, ma verrà comunque visualizzata nella barra degli indirizzi dell'utente come post-title-with-ç-and-õ.
Dietrich Epp,

7
I tuoi lettori sono portoghesi, quindi usa caratteri portoghesi.
Dietrich Epp,

107

Ci sono due serie di personaggi a cui devi fare attenzione: riservati e non sicuri .

I caratteri riservati sono:

  • e commerciale ("&")
  • dollaro ("$")
  • segno più ("+")
  • virgola (",")
  • barra ("/")
  • due punti (":")
  • punto e virgola (";")
  • equals ("=")
  • punto interrogativo ("?")
  • Simbolo "At" ("@")
  • libbra ("#").

I personaggi generalmente considerati non sicuri sono:

  • spazio (" ")
  • minore di e maggiore di ("<>")
  • parentesi aperte e chiuse ("[]")
  • apri e chiudi parentesi graffe ("{}")
  • pipe ("|")
  • barra rovesciata ("\")
  • caret ("^")
  • per cento ("%")

Forse ne ho dimenticato uno o più, il che mi porta a fare eco alla risposta di Carl V. A lungo termine probabilmente stai meglio usando una "lista bianca" di caratteri consentiti e quindi codificando la stringa anziché cercare di stare al passo con i caratteri non consentiti da server e sistemi.


#è un carattere riservato utilizzato per i segnalibri su una pagina specifica, creato con un elemento HTML con un attributo nome o un attributo id corrispondente (sans #-symbol).
TheLonelyGhost

Grazie - ho aggiornato la risposta.
Gary.Ray

Il punto interrogativo appare qui riservato e non sicuro - lo considero solo riservato, ma potrei non essere corretto
Jonathan Basile

6
Altri sembrano non essere d'accordo sul fatto che la tilde ~non sia sicura. Sei sicuro che lo sia?
drs

3
La lista bianca non è ottimale se si gestiscono lingue diverse dall'inglese. Unicode ha solo troppi punti di codice OK. Pertanto, la lista nera di quelli non sicuri è probabilmente la più facile da implementare nelle espressioni regolari.
Patanjali,

41

È meglio conservare solo alcuni caratteri (lista bianca) invece di rimuovere determinati caratteri (lista nera).

Puoi tecnicamente consentire qualsiasi personaggio, purché lo codifichi correttamente. Ma, per rispondere nello spirito della domanda, dovresti consentire solo a questi personaggi:

  1. Lettere minuscole (converti maiuscole in minuscole)
  2. Numeri, da 0 a 9
  3. Un trattino - o trattino basso _
  4. Tilde ~

Tutto il resto ha un significato potenzialmente speciale. Ad esempio, potresti pensare di poter usare +, ma può essere sostituito con uno spazio. ed è anche pericoloso, specialmente se si usano alcune regole di riscrittura.

Come per gli altri commenti, controlla gli standard e le specifiche per i dettagli completi.


15
Un preiodo, ho scoperto oggi, è una cattiva scelta di carattere da utilizzare per un codificatore Base64 sicuro per l'URL, perché ci saranno quei rari casi in cui i dati codificati possono produrre due punti consecutivi (".."), che è significativo in che fa riferimento alla directory principale.
pohl,

5
@pohl: questo è solo un problema se il tuo URL viene utilizzato come percorso di un file, nel tuo codice o se il tuo server web in realtà cerca di mappare l'URL ai file prima di inoltrare la richiesta a uno script (purtroppo molto comune).
André Caron,

4
In realtà, nel nostro caso usarlo come percorso di un file sarebbe ok, dato che nei file unix è permesso avere più punti, anche consecutivi, nei loro nomi. Per noi, il problema è sorto in uno strumento di monitoraggio chiamato Site Scope che presenta un bug (forse una regex ingenua) e riportava falsi tempi di inattività falsi. Per noi, siamo bloccati su una vecchia versione di Site Scope, il team di amministrazione si rifiuta di pagare per un aggiornamento e un cliente molto importante ha Site Scope (non equivalente) scritto nel loro contratto. Certo, la maggior parte non si troverà nei miei panni.
Pohl,

8
Grazie a Dio qualcuno ha pubblicato un elenco senza troppe chiacchiere. Per quanto riguarda il punto (.) - come diceva @pohl, non usarlo! Ecco un altro caso strano su IIS (non so se questo accade su altri Web Server): se si trova alla fine del tuo URL molto probabilmente riceverai un errore 404 (proverà a cercare [/ nomepagina]
.pag

34

Sempre al sicuro

Questi sono sicuri (in teoria / specifiche), praticamente ovunque tranne il nome del dominio.
Codifica in percentuale tutto ciò che non è elencato e sei a posto.

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

A volte sicuro

Sicuro solo se utilizzato all'interno di componenti URL specifici; usare con cura.

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

Mai al sicuro

Secondo le specifiche URI (RFC 3986), tutti gli altri caratteri devono essere codificati in percentuale. Ciò comprende:

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

Se la massima compatibilità è un problema, limitare il set di caratteri a AZ az 0-9 - _.
(con punti solo per le estensioni dei nomi).

Tieni presente il contesto

Anche se valido per specifica, un URL può essere comunque "non sicuro", a seconda del contesto. Ad esempio un file: /// URL contenente caratteri di nome file non validi o un componente di query contenente "?", "=" E "&" quando non utilizzato come delimitatori. La corretta gestione di questi casi dipende generalmente dai tuoi script e può essere risolta, ma è qualcosa da tenere a mente.


Potresti fornire qualche fonte per il tuo secondo reclamo ("A volte sicuro")? In particolare, credo che ti sbagli nel dire che =non è sicuro per le domande. Ad esempio, FIQL accetta segni di uguaglianza e si descrive come "compatibile con URI" e "ottimizzato e destinato all'uso nel componente di query". Nella mia interpretazione, RFC 3986 consente esplicitamente "=", "&", "+" e altri nelle query.
DanielM,

@DanielM "?", "=" E "&" sono validi nelle query per specifica, sebbene in pratica siano ampiamente utilizzati per analizzare coppie nome-valore all'interno della query. Quindi possono non essere sicuri come parte dei nomi / valori stessi. Se ciò costituisca o meno "pericoloso" può essere una questione di opinione.
Beejor,

Alcune fonti, come richiesto. (1) RFC 3986, Sec 3.4: "I [...] componenti di query vengono spesso utilizzati per trasportare informazioni identificative sotto forma di coppie" chiave = valore "[...]" (2) WhatWG URL Spec, Sec. 6.2: "Costruire e stringere un oggetto URLSearchParams è abbastanza semplice: [...] params.toString() // "key=730d67"" (3) Manuale PHP, http-build-query: "Genera stringa di query con codifica URL. [...] L'esempio sopra mostrerà: 0=foo&1=bar[...]"(4) J. Starr, Perishable Press:" Quando si creano pagine Web, è spesso necessario aggiungere collegamenti che richiedono stringhe di query con parametri. "
Beejor,

@Beejor: sto costruendo un URL e utilizzo '-' e ';' durante la costruzione. Non è un'app Web ma un'app mobile. Non uno sviluppatore web e quindi, sarei al sicuro se uso i due caratteri precedenti nella proprietà Path? docs.microsoft.com/en-us/dotnet/api/…
karsnen il

1
@karsnen Questi sono caratteri URL validi. Tuttavia, se utilizzato per fare riferimento a percorsi su un filesystem locale, tenere presente che alcuni sistemi non consentono determinati caratteri nei nomi dei file. Ad esempio, "file: /// path / to / my: file.ext" non sarebbe valido su Mac.
Beejor,

17

Guardando RFC3986 - Uniform Resource Identifier (URI): sintassi generica , la tua domanda ruota attorno al componente del percorso di un URI.

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

Citando la sezione 3.3, i caratteri validi per un URI segmentsono di tipo pchar:

pchar = non prenotato / codificato PCT / sub-delim / ":" / "@"

Che si suddivide in:

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

pct-encoded

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

":" / "@"

O in altre parole: è possibile utilizzare qualsiasi carattere (non-Controller) dalla tabella ASCII , tranne / , ?, #, [e ].

Questa comprensione è supportata da RFC1738 - Uniform Resource Locator (URL) .


2
Questo è un grande esempio di una risposta teoricamente corretta, che porta a problemi quando viene applicato al mondo reale in cui viviamo realmente. È vero che la maggior parte di quei personaggi non causerà un problema la maggior parte delle volte. Ma esistono nel mondo reale cose come proxy, router, gateway, relè, ecc., Che "amano" ispezionare e interagire con gli URL in modi che ignorano lo standard teorico. Per evitare queste insidie, sei praticamente limitato a sfuggire a tutto tranne alfanumerici, trattino, trattino basso e punto.
deltamind106,

1
@ deltamind106 Puoi fornire esempi e / o riferimenti per chiarire quale di questi caratteri sicuri secondo le RFC non lo sono? Preferirei attenermi ai fatti sostenuti dagli standard nella mia risposta, e sono felice di aggiornare la mia risposta se riesci a individuare eventuali fatti che potrei aver trascurato.
Philzen,

2
@ deltamind106 Suggerirei di provare a far sì che i prodotti seguano gli standard anziché dire agli sviluppatori di non farlo. Ritengo che il tuo avviso sia meritato, ma dovremmo fare la nostra parte nel segnalare la non conformità ai fornitori, se necessario.
Lo-Tan,

@Philzen: sto costruendo un URL e utilizzo '-' e ';' durante la costruzione. Non è un'app Web ma un'app mobile. Non uno sviluppatore web e quindi, sarei al sicuro se uso i due caratteri precedenti nella proprietà Path? docs.microsoft.com/en-us/dotnet/api/…
karsnen il

1
@karsnen Sì, certo -e ;sono al sicuro, questo è ciò che la mia risposta e RFC affermano chiaramente.
Philzen,

12

senza prenotazione = ALPHA / DIGIT / "-" / "." / "_" / "~"


3
"ALPHA" non implica "DIGIT"? Presumo che ALPHA sia l'abbreviazione di "alfanumerico" e alfanumerico significa lettere maiuscole, minuscole e cifre.
Luc,

11
In realtà l'alfa non implica alfanumerico. Alfa e numerico sono 2 cose distinte e alfanumerico è la combinazione di quelle cose. Avrebbe potuto scrivere la sua risposta in questo modo: ALPHANUMERIC / "-" / "." / "_" / "~"
MacroMan

1
La notazione ABNF per "senza prenotazione" in RFC 3986 li elenca separatamente.
Patanjali,

11

Dal contesto che descrivi, sospetto che ciò che stai effettivamente cercando di creare sia qualcosa chiamato "lumaca SEO". La migliore pratica generale conosciuta per quelli è:

  1. Converti in minuscolo
  2. Converti intere sequenze di caratteri diversi da az e 0-9 in un trattino (-) (non caratteri di sottolineatura)
  3. Rimuovi "stop words" dall'URL, ovvero parole non indicizzabili come "a", "an" e "the"; Google "stop words" per elenchi completi

Quindi, ad esempio, un articolo intitolato "L'utilizzo di! @% $ * Per rappresentare il giuramento nei fumetti" otterrebbe una lumaca di "utilizzo-rappresentano-giuramento-fumetti".


È davvero un buon approccio per rimuovere queste "parole d'arresto" dall'URL? I motori di ricerca penalizzerebbero un sito Web per questo?
Paulo,

In genere si ritiene che i motori di ricerca riconoscano solo una parte dell'URL e / o diano un significato ridotto a porzioni successive, quindi rimuovendo le parole di arresto ciò che stai facendo è massimizzando il numero di parole chiave incorporate nel tuo URL che hai una possibilità di effettivamente classifica su.
caos,

1
@chaos Mi consiglia comunque di eliminare StopWord, se si tiene conto di questo: seobythesea.com/2008/08/google-stopword-patent Inoltre, è possibile consigliare un buon elenco di password? Questa è la migliore lista che ho trovato finora - link-assistant.com/seo-stop-words.html
nikib3ro

@ kape123 Per me non sembra un elenco molto valido. "c" e "d" sono linguaggi di programmazione e molte di queste altre parole sembrano significative. Probabilmente eliminerei solo quelli di base: a, e, is, on, of, or, the, with.
Aprire il

6

Il formato per un URI è definito in RFC 3986 . Vedere la sezione 3.3 per i dettagli.


6

Dal punto di vista SEO, i trattini sono preferiti ai caratteri di sottolineatura. Converti in minuscolo, rimuovi tutti gli apostrofi, quindi sostituisci tutte le stringhe di caratteri non alfanumerici con un singolo trattino. Taglia i trattini in eccesso all'inizio e alla fine.


3

Ho avuto un problema simile, volevo avere abbastanza URL e sono arrivato alla conclusione che devo consentire solo lettere, cifre, e _ negli URL. Va bene, poi ho scritto un bel regex e mi sono reso conto che riconosce che tutti i caratteri UTF8 non sono lettere in .NET ed è stato fregato. Questo sembra essere un problema noto per il motore regex .NET. Quindi sono arrivato a questa soluzione:

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 "-";
    }
}

3
Le regex .NET supportano abbastanza bene Unicode. Devi usare le classi di caratteri unicode, ad esempio \ p {L} per tutte le lettere. See msdn.microsoft.com/en-us/library/20bw873z.aspx#CategoryOrBlock
TheCycoONE

1

Ho trovato molto utile codificare il mio url in uno sicuro quando stavo restituendo un valore tramite ajax / php a un url che è stato poi letto nuovamente dalla pagina.

Uscita PHP con encoder url per il carattere speciale e

//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);

Spero che qualcuno trovi utili i miei piccoli estratti di codice! :)



-4

Tra 3-50 caratteri. Può contenere lettere minuscole, numeri e caratteri speciali: punto (.), Trattino (-), trattino basso (_) e alla velocità (@).


4
Qualche riferimento per quello?
dakab,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.