2012-06-24 9 views
11

Quando si esegue il rendering del seguente testo Unicode in HTML, risulta che il browser (Google Chrome) esegue una qualche forma di Unicode normalization quando si rinviano i dati sul server. (Probabilmente in Form C).Come evitare i browser Normalizzazione Unicode quando si invia un modulo con Unicode

Tuttavia, quando si utilizza il testo in ebraico biblico (בְּרִיךְ הוּא), questo può facilmente interrompere il testo, come indicato in here (pagina 9).

C'è un modo per evitare la normalizzazione automatica del testo del browser?

ho scritto un post sul blog che descrivono più in dettaglio il problema che sto affrontando: http://blog.hibernatingrhinos.com/12449/would-it-be-possible-to-have-a-web-browser-based-editor-for-an-hebrew-text

+0

@Hans no. Perchè la pensi così? –

+0

Non puoi semplicemente applicare la soluzione descritta nello stesso documento? – jalf

+1

E di quali browser specifici stai chiedendo? Non esiste un'unica API standardizzata per "disabilitare la normalizzazione quando si inviano moduli", per quanto ne so. I singoli browser possono o meno avere un'opzione per controllarlo. E vuoi che il tuo sito web disabiliti la normalizzazione, o un modo per l'utente del browser di configurare il suo browser per non normalizzarlo? – jalf

risposta

10

Questo sembra un essere una caratteristica/bug nel browser WebKit (Chrome, Safari); normalizzano i dati del modulo in NFC, il che significa, tra le altre cose, il riordino dei marchi combinati consecutivi in ​​un ordine "canonico". Questo era nuovo per me e cattive notizie in casi come questo. La cosa peggiore è che i diversi browser si comportano diversamente.

Utilizzo di una versione semplificata del test case http://blog.hibernatingrhinos.com/12449/would-it-be-possible-to-have-a-web-browser-based-editor-for-an-hebrew-text (utilizzando uno script sul lato server che fa solo eco ai dati non elaborati), ho notato che Chrome e Safari riordinano i segni diacritici in U + 05E9 U + 05C1 U + 05B5 (SHIN , SHIN DOT, TSERE), mentre IE, Firefox e Opera no.

Ho eseguito anche un semplice test con la lettera latina e seguito dalla combinazione di diaeresi U + 0308. I browser WebKit lo convertono nel singolo carattere ë, come da regole NFC, mentre altri browser mantengono intatta la coppia di caratteri.

Questa sembra essere una caratteristica intenzionale, dal 2006; https://bugs.webkit.org/show_bug.cgi?id=8769 annuncia con orgoglio questo come parte di una correzione di bug! Questo potrebbe spiegare lo stato del documento politico del W3C; la sua versione attuale è rivolta a WebKit in questo numero, ma altri produttori di browser non sono interessati o si oppongono consapevolmente all'idea di "normalizzazione anticipata".

Non penso che ci sia un modo per impedirlo. Ma potresti mettere in guardia gli utenti dall'usare Chrome e Safari. Potresti anche utilizzare un campo nascosto contenente un semplice caso problematico, quindi controllare sul lato server se è stato trasmesso così com'è, e dire all'utente di cambiare browser se non lo è.

Il fissaggio dell'ordine lato server non è semplice, perché le normali routine di normalizzazione apparentemente non supportano l'ordine necessario. È possibile normalizzare in una forma completamente decomposta (NFD), quindi riordinare i segni combinati utilizzando il proprio codice per lo scopo. Forse più semplice e più sicuro, si può semplicemente eseguire una routine sostitutiva ad hoc che sostituisce sequenze di combinazione di marchi con altre sequenze. Questo sarebbe più sicuro perché non influenzerebbe i caratteri diversi da quelli che si desidera influenzare, mentre NFD decifra le lettere latine con segni diacritici, tra le altre cose.

Secondo i principi Unicode, le stringhe canonicamente equivalenti (ad esempio, che differiscono solo nell'ordine dei segni diacritici consecutivi) sono rappresentazioni differenti degli stessi dati ma distinte come sequenze di caratteri Unicode (punti di codice); non ci si aspetta che differiscano nella presentazione, ma possono, e spesso lo fanno. In genere, non è necessario attendere programmi per trattare le stringhe canonicamente equivalenti come diverse, anche se i programmi possono fare la differenza con. Vedi Unicode Normalization FAQ.

La voce FAQ afferma che i problemi dell'ebraico biblico sono stati risolti dall'introduzione di COMBINING GRAPHEME JOINER. Sebbene prevenga il riordino in Chrome, è un metodo maldestro, e può rovinare il rendering (lo fa nei browser web, i segni diacritici possono essere mal riposti).

+0

Penso che questo sia più un bug che una funzionalità, dal momento che la normalizzazione non si verifica sul rendering del testo, ma del modulo submit. A questo punto, le decisioni sulla normalizzazione dovrebbero essere quelle del server, non del browser. –

+0

Ho creato un problema per questo, https://code.google.com/p/chromium/issues/detail?id=134623&thanks=134623&ts=1340703693 –

+0

+1: "Ma potresti avvisare gli utenti di non utilizzare Chrome e Safari." Di solito l'utente è avvisato sull'uso di ie6-8. –

0

È possibile modificare il testo sul lato client prima dell'invio. Se si inserisce un combinatore Grapheme Joiner, è possibile inserirlo tramite JavaScript.

Come punto fisso, ma ecco un JSFiddle che ottiene la lettera di caratteri per lettera (testato in Safari e non normalizzare il testo): http://jsfiddle.net/TmtnA/

1

E 'possibile evitare la normalizzazione stringa inviando un Uint8Array piuttosto che una stringa. In primo luogo, ottenere i dati UTF-8 della stringa come Uint8Array come descritto here da @Moshev:

function utf8AbFromStr(str) { 
    var strUtf8 = unescape(encodeURIComponent(str)); 
    var ab = new Uint8Array(strUtf8.length); 
    for (var i = 0; i < strUtf8.length; i++) { 
     ab[i] = strUtf8.charCodeAt(i); 
    } 
    return ab; 
} 

, puoi postarla che Uint8Array con XHR normale o la vostra libreria preferita Ajax. Se stai usando jQuery, tieni presente che devi specificare processData: false per impedire a jQuery di provare a renderizzarlo e annullare tutto il tuo duro lavoro.