Domanda

Se si guarda a questo tavolo qui , ha un elenco di sequenze di escape per i caratteri Unicode che in realtà non funziona per me.

Ad esempio per "% 96", che dovrebbe essere un -, ottengo un errore durante il tentativo di decodifica:

decodeURIComponent("%96");
URIError: URI malformed

Se tento di codificare "-" Io in realtà ottengo:

encodeURIComponent("–");
"%E2%80%93"

Ho cercato attraverso internet e ho visto questo pagina , che menziona utilizzando rispettivamente fuga e unescape con decodeURIComponent e encodeURIComponent. Questo non sembra aiuto perché% 96 non si presenta come "-" non importa quello che cerco e questo naturalmente non sarebbe lavoro:

decodeURIComponent(escape("%96));
"%96"

Non molto utile.

Come posso ottenere "% 96" per essere un "-" con JavaScript (senza hardcoding una mappa per ogni singolo carattere Unicode possibile io possa correre in)?

È stato utile?

Soluzione

Il %XX sequenza in un URI codifica un "ottetto", cioè un byte di otto bit. Ciò pone il problema di quale carattere Unicode che il byte decodificato riferisce. Se la mia memoria non mi inganna, nelle versioni precedenti della specifica URI, non è stato ben definito che cosa charset è stato assunto. Nelle versioni successive delle specifiche URI è stato raccomandato che UTF-8 sia il charset codifica predefinita. Che è, per decodificare una sequenza di byte, si potrebbe decodificare ogni sequenza %XX e quindi convertire i byte risultanti in una stringa utilizzando il set di caratteri UTF-8.

Questo spiega perché %96 non decodificare. Il valore esadecimale 0x96 non è una sequenza UTF-8 valido. Come è sta al di là ASCII, che avrebbe bisogno di una speciale byte modificatore di prima per indicare un carattere esteso. (Si veda la specifica UTF-8 per maggiori dettagli.) I encodeURIComponent() e decodeURIComponent() metodi JavaScript sia assumere UTF-8 (come dovrebbero), quindi non mi aspetto correttamente %96 per la decodifica.

Il personaggio si fa riferimento è U + 2013, un en-dash. Come diavolo fa la pagina si fa riferimento a ottenere un en-dash da hex 0x96 (decimale 150)? Essi non sono ovviamente assumendo codifica UTF-8, che è lo standard. Essi non stanno assumendo ASCII, che non contiene questo carattere. Essi non sono anche ammettendo ISO-8859-1 , che è una codifica standard utilizza un byte per carattere. Si scopre che stanno assumendo la speciale di Windows 1252 tabella codici . Vale a dire, l'URI yo u stanno cercando di decodificare presuppone che l'utente si trova su una macchina Windows, e, peggio ancora, su una macchina Windows in lingua inglese (o uno di poche altre lingue occidentali).

In breve, il tavolo che si sta utilizzando è male. E 'out-of-date e si presuppone che l'utente si trova su un sistema inglese di Windows. L'up-to-date e modo corretto di valori non-ASCII codifica è quello di convertirli in UTF-8 e quindi codificare ogni ottetto utilizzando %XX. È per questo che avete ottenuto %E2%80%93 quando si è tentato di codificare il carattere, ed è quello che si aspetta decodeURIComponent(). L'URI che si sta utilizzando non è codificato in modo corretto. Se non avete altra scelta, si può intuire che l'URI utilizza Windows 1252, convertire il te stesso byte, e quindi utilizzare un tavolo di Windows 1252 per scoprire quali valori Unicode erano destinati. Ma che è rischioso --- come fai a sapere che URI usi che di tabella? Ecco perché tutti si stabilirono su UTF-8. Se possibile, dirà chi si sta dando questi URI per codificare correttamente.

Altri suggerimenti

distacco come voce della comunità wiki come è da "costruzione di siti web scalabili" di Carl Henderson. Il libro dice che è OK per riprodurre porzioni significative degli esempi però. Si può essere in grado di creare un caso speciale per "-". Con esso

function escape_utf8(data) {
        if (data == '' || data == null){
               return '';
        }
       data = data.toString();
       var buffer = '';
       for(var i=0; i<data.length; i++){
               var c = data.charCodeAt(i);
               var bs = new Array();
              if (c > 0x10000){
                       // 4 bytes
                       bs[0] = 0xF0 | ((c & 0x1C0000) >>> 18);
                       bs[1] = 0x80 | ((c & 0x3F000) >>> 12);
                       bs[2] = 0x80 | ((c & 0xFC0) >>> 6);
                   bs[3] = 0x80 | (c & 0x3F);
               }else if (c > 0x800){
                        // 3 bytes
                        bs[0] = 0xE0 | ((c & 0xF000) >>> 12);
                        bs[1] = 0x80 | ((c & 0xFC0) >>> 6);
                       bs[2] = 0x80 | (c & 0x3F);
             }else if (c > 0x80){
                      // 2 bytes
                       bs[0] = 0xC0 | ((c & 0x7C0) >>> 6);
                      bs[1] = 0x80 | (c & 0x3F);
               }else{
                       // 1 byte
                    bs[0] = c;
              }
             for(var j=0; j<bs.length; j++){
                      var b = bs[j];
                       var hex = nibble_to_hex((b & 0xF0) >>> 4) 
                      + nibble_to_hex(b &0x0F);buffer += '%'+hex;
              }
    }
    return buffer;
}
function nibble_to_hex(nibble){
        var chars = '0123456789ABCDEF';
        return chars.charAt(nibble);
}

questa domanda , in particolare questa risposta :

  

c'è uno speciale “% unnnn” formato per   codifica Unicode UTF-16 punti di codice,   invece di codificare UTF-8 byte

Ho il sospetto "-" è uno di quei personaggi dal 0x96 al ASCII TAVOLA è pari a U

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top