Strumenti per sviluppatori · URL codificatore e decodificatore
WHATWG URL Standard vs RFC 3986: perché browser e librerie non sono d'accordo
· Sfondo
codifica dell'URL standard strumenti per sviluppatori
Esistono due definizioni viventi di URL e sono in disaccordo di proposito. Questo post spiega perché WHATWG ha scritto il proprio standard, dove i due differiscono nella codifica e nell'analisi e quale segue il tuo codice.
Il URL che una libreria rigorosa rifiuta e il browser carica felicemente: una stringa, due verdetti
Una stringa con una barra rovesciata in JavaScript potrebbe essere interpretata correttamente dal browser come parte del percorso URL. La stessa stringa raggiunge il backend della libreria Python e si rifiuta di analizzarla perché le barre rovesciate non sono consentite. Un URL, due risultati diversi. Nessuno dei due è sbagliato: seguono standard diversi. Lo standard WHATWG descrive cosa fanno effettivamente i browser con gli URL del mondo reale, incluso il modo in cui gestiscono l'input non valido. RFC 3986 definisce una grammatica formale a cui gli URL dovrebbero idealmente conformarsi. Molte librerie backend basate su RFC 3986 applicano rigorosamente quella grammatica e rifiutano qualsiasi cosa al di fuori di essa.
Questa divergenza è importante quando si spostano i dati tra ambienti. L'accettazione da parte dei browser URL potrebbe non riuscire a convalidare in uno strumento di backend. Capire quale standard implementa il tuo codice previene il debug di problemi fantasma: gli URL funzionano bene in un posto ma falliscono misteriosamente da qualche altra parte senza una ragione apparente.
Perché WHATWG ha ricominciato da capo: descrive cosa fanno realmente i browser con input non validi anziché con ciò che è valido
Il gruppo di lavoro WHATWG formato in 2004 per standardizzare il modo in cui i browser gestiscono effettivamente gli URL nella pratica, piuttosto che definire regole formali più rigide che i browser non seguirebbero. RFC 2396 descriveva una specifica grammaticale formale, ma i browser in pratica non la seguivano mai esattamente correttamente. I browser del mondo reale hanno sviluppato regole pratiche per tollerare gli spazi, gestire i caratteri di escape e recuperare da input errati che RFC non aveva previsto o previsto.
RFC 3986 è arrivato in 2005 con una grammatica formale per URL ben formati e requisiti rigorosi. I browser implementano WHATWG; le librerie backend spesso implementano RFC 3986.
Set di codifica e caratteri riservati: come gli elenchi per componente di URL Standard si riferiscono alle categorie di RFC 3986
RFC 3986 divide i caratteri in tre categorie: riservati, non riservati e tutto il resto che deve essere codificato. I caratteri riservati come i due punti, la barra, il punto interrogativo e l'hash hanno un significato strutturale negli URL. I caratteri non riservati sono lettere, cifre, trattino, carattere di sottolineatura, punto e tilde; questi sono sempre sicuri. Tutto il resto viene codificato in percentuale come byte. Lo standard fornisce una regola chiara: sapere a quale categoria appartiene il tuo personaggio.
Lo standard WHATWG URL adotta un approccio basato sui componenti. Specifica diverse regole di codifica per schema, autorità, percorso, query e frammento separatamente invece di utilizzare categorie globali. Una e commerciale potrebbe essere codificata in un percorso ma lasciata sola in una stringa di query. Uno spazio è sempre codificato, ma la rappresentazione esatta varia a seconda del contesto. Questa progettazione per componente corrisponde molto meglio al comportamento del browser, ma richiede di sapere quale parte di URL stai codificando.
Tolleranza agli errori: spazi, barre rovesciate e tabulazioni: gli input vengono rifiutati da uno standard e riparati dall'altro
Gli spazi devono diventare %20 in entrambi gli standard, ma i browser convertono automaticamente gli spazi letterali. Le barre rovesciate sono vietate da entrambi gli standard, tuttavia alcuni browser le trattano come separatori di percorso. Sono vietati tabulazioni, ritorni a capo e caratteri di controllo. WHATWG specifica il comportamento indulgente del parser: convertirli o ignorarli.
I caratteri diversi da ASCII come é o 中 devono essere codificati in percentuale utilizzando la codifica UTF-8. RFC 3986 in realtà non specifica il passaggio di codifica dei caratteri stesso; presuppone che esistano i byte ma non dice come ottenerli dal testo. Lo standard WHATWG richiede esplicitamente UTF-8: trasforma prima la stringa in UTF-8 byte, quindi codificali in percentuale. Entrambi gli standard raggiungono lo stesso risultato di codifica, ma partono da presupposti di base diversi e non sono espliciti sulle stesse cose.
Esempio realizzato: analisi di URL con una barra rovesciata e uno spazio in entrambi i modelli: gli output confrontati
Prendi la stringa di esempio "https://example.com/café\ search". Un browser rileva la barra rovesciata e la vede come un carattere di percorso; vede lo spazio e lo codifica in %20, producendo qualcosa come https://example.com/café%5C%20search. Un parser RFC 3986 rifiuta immediatamente l'intero URL perché le barre rovesciate sono vietate e gli spazi sono vietati. Il browser continua l'analisi; il parser rigoroso si ferma completamente. Prova un altro esempio: "https://user@example.com:80/path?q=a&b=c". Entrambi gli standard identificano chiaramente le informazioni utente, l'host, la porta, il percorso e la query. Sono completamente d'accordo su questo URL strutturato. Il disaccordo si verifica solo su input insoliti o non corretti.
Apri il codificatore e decodificatore URL e confronta la modalità RFC 3986 con il comportamento del browser. Incolla una stringa con spazi, barre rovesciate o altri casi limite. Lo strumento mostra esattamente come ciascuno standard trasforma lo stesso input in modo diverso. Vedi immediatamente quale è più severo e cosa fa ciascuno.
Quale utilizza il tuo ambiente: i browser e il nodo seguono lo standard URL; molte librerie server seguono RFC, descritto in generale
Nei browser, JavaScript utilizza lo standard WHATWG URL per impostazione predefinita. Il URL API lo implementa esattamente. Node.js utilizza anche WHATWG. Le librerie Python tendono a implementare RFC 3986; urllib lo segue da vicino. Le librerie Java variano; java.net.URL tende verso RFC 3986. Il contenitore degli URL di Rust segue WHATWG. La rete di Go/url è influenzata da WHATWG. Questo è uno schema generale, non una regola assoluta.
Quando crei URL in modo programmatico e questi si spostano tra il browser e il backend, scegli uno standard e attieniti ad esso. Utilizza URL API del browser per WHATWG. Se la tua libreria backend è più rigorosa, non è una contraddizione ma una scelta progettuale.
Cosa non copre: analisi del nome host, valori letterali IPv6 ed elaborazione IDNA
L'analisi del nome host coinvolge IDNA, punycode e regole del registrar che vanno oltre l'intera analisi di URL. Gli indirizzi IPv6, gli schemi speciali come mailto: o data: e i componenti vuoti sono argomenti separati completamente distinti dalla codifica percentuale. I limiti di lunghezza del dominio e la validità del nome host variano a seconda del registrar e non sono rilevanti per questa discussione. Sono inoltre esclusi: riferimenti relativi e regole di analisi specifiche dello schema. Questo post si concentra solo sulla codifica e sull'analisi delle differenze.
Questa discussione si concentra sulle differenze di codifica e analisi che distinguono questi standard. L'esclusione delle regole del nome host, delle regole DNS e del comportamento specifico dello schema impedisce confusione sulle regole di codifica percentuale.
Conclusione: lo stesso URL è valido in un mondo e un errore in un altro: come il codificatore e decodificatore URL ti fornisce la semplice codifica RFC 3986 in modo da poter vedere cosa è stato normalizzato dal browser
La stessa stringa URL può essere valida secondo uno standard e non valida secondo un altro. Entrambi sono corretti entro i propri obiettivi di progettazione. Quando codifichi i componenti URL a livello di codice, utilizza lo strumento giusto per il tuo ambiente. WHATWG descrive cosa fanno effettivamente i browser; RFC 3986 definisce la grammatica formale. Il codificatore e decodificatore URL mostra le regole RFC 3986 insieme al comportamento del browser in modo da poter vedere le differenze esatte e scegliere quale si adatta alla tua situazione.
I problemi si verificano più spesso quando gli URL superano i limiti del browser e del backend. Comprendere questa differenza significa gestire quell'attraversamento intenzionalmente piuttosto che accidentalmente o per errore.