2012-06-21 15 views
27

Dopo una frenetica ricerca di Google, non riesco a trovare una risposta definitiva a una semplice domanda. Mi scuso se questa domanda è una risposta a qualche parte, ma se così fosse non potrei trovarla.Codifica caratteri Javascript predefinita?

Durante la scrittura di un metodo di crittografia in Javascript, sono arrivato a chiedermi quale carattere codificante le mie stringhe stessero utilizzando e perché.

Quindi: cosa determina la codifica dei caratteri in Javascript? È uno standard? Dal browser? Determinato dall'intestazione della richiesta HTTP? Nel tag <META> di HTML che lo comprende? Il server che alimenta la pagina?

Con il mio test empirico (cambiando diverse impostazioni, quindi usando charCodeAt su un personaggio sufficientemente strano e vedendo con quale codifica corrisponde il valore) sembra essere sempre UTF-8 o UTF-16, ma non sono sicuro why.

Grazie per l'aiuto!

+3

Le stringhe JavaScript sono sempre UTF-16. – Pointy

+0

Immagino che sia solo la risposta allora. Per favore, dove è documentato? –

+0

Sto cercando di individuarlo nel documento ECMA-262 ora :-) – Pointy

risposta

22

sezione 8.4 di E262:

Il tipo String è l'insieme di tutte le sequenze finite ordinate di zero o più valori senza segno interi a 16 bit (“elementi”). Il tipo di stringa viene generalmente utilizzato per rappresentare i dati testuali in un programma ECMAScript in esecuzione, nel qual caso ogni elemento della stringa viene considerato come un valore di unità di codice (vedere Clausola 6). Ogni elemento è considerato come occupante una posizione all'interno della sequenza. Queste posizioni sono indicizzate con numeri interi non negativi. Il primo elemento (se presente) è in posizione 0, l'elemento successivo (se presente) nella posizione 1 e così via. La lunghezza di una stringa è il numero di elementi (cioè valori a 16 bit) al suo interno. La stringa vuota ha lunghezza zero e quindi non contiene elementi.

Quando una stringa contiene dati testuali effettivi, ogni elemento è considerato come una singola unità di codice UTF-16. Indipendentemente dal fatto che questo sia il formato di archiviazione effettivo di una stringa, i caratteri all'interno di una stringa sono numerati dalla posizione dell'elemento dell'unità di codice iniziale come se fossero rappresentati utilizzando UTF-16. Tutte le operazioni su Stringhe (eccetto che non sia diversamente specificato) le trattano come sequenze di numeri interi senza segno indifferenziati a 16 bit; non assicurano che la Stringa risultante sia in forma normalizzata, né garantiscono risultati sensibili alla lingua.

Tale formulazione è di tipo gentile; sembra voler dire che tutto ciò che conta considera le stringhe come se ogni personaggio fosse un carattere UTF-16, ma allo stesso tempo nulla garantisce che tutto sia valido.

modifica — per intenderci, il intento è che le stringhe sono costituite da UTF-16 codepoints. In ES2015, la definizione di "valore stringa" include questa nota:

Un valore stringa è un membro del tipo String. Ogni valore intero nella sequenza di solito rappresenta una singola unità a 16 bit di testo UTF-16. Tuttavia, ECMAScript non pone alcuna restrizione o requisito sui valori eccetto che devono essere numeri interi senza segno a 16 bit.

Quindi una stringa è ancora una stringa anche se contiene valori che non funzionano come caratteri Unicode corretti.

+1

Documentazione * e * traduzioni weasley-wording! Grazie! –

+3

Avvertenza: ogni elemento è un _code unit UTF-16_. Apparentemente le coppie surrogate valgono come due caratteri in una stringa, anche se codificano un singolo carattere Unicode. – lanzz

9

Non esiste una codifica di caratteri predefinita per JavaScript. Un programma JavaScript è, per quanto riguarda le specifiche, una sequenza di caratteri astratti.Quando vengono trasmessi su una rete, o semplicemente memorizzati in un computer, i caratteri astratti devono essere codificati in qualche modo, ma i meccanismi per esso non sono controllati dallo standard ECMAScript.

La sezione 6 dello standard ECMAScript utilizza UTF-16 come codifica di riferimento, ma non lo designa come predefinito. L'utilizzo di UTF-16 come riferimento non è logicamente superfluo (sarebbe sufficiente fare riferimento ai numeri Unicode), ma probabilmente è stato pensato per aiutare le persone.

Questo problema non deve essere confuso con l'interpretazione di stringhe letterali o stringhe in generale. Un letterale come "Φ" deve essere in qualche codifica, insieme al resto del programma; questa può essere una qualsiasi codifica, ma dopo che la codifica è stata risolta, il valore letterale sarà interpretato come un numero intero in base al numero Unicode del carattere.

Quando un programma JavaScript viene trasmesso come tale (come un "file JavaScript esterno") su Internet, vale RFC 4329, Tipi di supporti di scripting. La clausola 4 definisce il meccanismo: in primo luogo, le intestazioni come le intestazioni HTTP vengono controllate e un parametro charset su cui verrà eseguito l'attendibile. (In pratica, i server web di solito non specificano un tale parametro per i programmi JavaScript.) In secondo luogo, viene applicato il rilevamento BOM. In caso contrario, UTF-8 è implicito.

La prima parte del meccanismo è piuttosto ambigua. Potrebbe essere interpretato come relativo al parametro charset solo in un'intestazione HTTP effettiva oppure potrebbe essere esteso ai parametri charset negli elementi script.

Se un programma JavaScript appare come incorporato in HTML, tramite un elemento script o qualche attributo evento, la codifica dei caratteri è ovviamente la stessa di quella del documento HTML. La sezione Specifying the character encoding della specifica HTML 4.01 definisce il meccanismo di risoluzione, in questo ordine: charset nell'intestazione HTTP, charset in meta, charset in un collegamento seguito per accedere al documento e infine euristica (congettura), che può comportare molte cose; cf. al complesso resolution mechanism in the HTML5 draft.

+2

Affascinante - ma per me, molto di questo suona come il vero file Javascript stesso verrà codificato, al contrario del modo in cui Javascript gestisce stringhe letterali nel suo codice. Sto fraintendendo? –

+0

La mia risposta riguardava davvero la codifica dei caratteri dei programmi JavaScript. Non esiste una codifica di caratteri separata per i valori letterali JavaScript: 'abc' indica una sequenza di tre numeri interi a 16 bit, che sono i numeri Unicode per a, b e c. Se sembra che fossero in qualche modo "codificati in UTF-8" in modo da ottenere byte UTF-8 durante la lettura di una stringa, allora c'è qualche incomprensione. Ma per i caratteri Ascii, 'a' sta per un intero a 16 bit che consiste nel byte da 8 bit per 'a' in Ascii e un byte zero, quindi i dati potrebbero * apparire * come codificati in UTF-8. –

Problemi correlati