J'ai JavaScript dans une page Web XHTML qui transmet des chaînes codées en UTF-8. Il doit continuer à adopter la version UTF-8 et à la décoder. Comment est-il possible de décoder une chaîne UTF-8 pour l'affichage?
<script type="text/javascript">
// <![CDATA[
function updateUser(usernameSent){
var usernameReceived = usernameSent; // Current value: Größe
var usernameDecoded = usernameReceived; // Decode to: Größe
var html2id = '';
html2id += 'Encoded: ' + usernameReceived + '<br />Decoded: ' + usernameDecoded;
document.getElementById('userId').innerHTML = html2id;
}
// ]]>
</script>
Pour répondre à la question initiale: voici comment décoder utf-8 en javascript:
http://ecmanaut.blogspot.ca/2006/07/encoding-decoding-utf8-in-javascript.html
Plus précisément,
function encode_utf8(s) {
return unescape(encodeURIComponent(s));
}
function decode_utf8(s) {
return decodeURIComponent(escape(s));
}
Je viens de l'utiliser dans mon code, et cela fonctionne parfaitement.
Cela devrait fonctionner:
// http://www.onicos.com/staff/iz/amuse/javascript/expert/utf.txt
/* utf.js - UTF-8 <=> UTF-16 convertion
*
* Copyright (C) 1999 Masanao Izumo <[email protected]>
* Version: 1.0
* LastModified: Dec 25 1999
* This library is free. You can redistribute it and/or modify it.
*/
function Utf8ArrayToStr(array) {
var out, i, len, c;
var char2, char3;
out = "";
len = array.length;
i = 0;
while(i < len) {
c = array[i++];
switch(c >> 4)
{
case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
// 0xxxxxxx
out += String.fromCharCode(c);
break;
case 12: case 13:
// 110x xxxx 10xx xxxx
char2 = array[i++];
out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F));
break;
case 14:
// 1110 xxxx 10xx xxxx 10xx xxxx
char2 = array[i++];
char3 = array[i++];
out += String.fromCharCode(((c & 0x0F) << 12) |
((char2 & 0x3F) << 6) |
((char3 & 0x3F) << 0));
break;
}
}
return out;
}
Découvrez la démo JSFiddle .
La solution de @ albert était la plus proche, mais elle ne peut analyser que 3 caractères utf-8
function utf8ArrayToStr(array) {
var out, i, len, c;
var char2, char3;
out = "";
len = array.length;
i = 0;
// XXX: Invalid bytes are ignored
while(i < len) {
c = array[i++];
if (c >> 7 == 0) {
// 0xxx xxxx
out += String.fromCharCode(c);
continue;
}
// Invalid starting byte
if (c >> 6 == 0x02) {
continue;
}
// #### MULTIBYTE ####
// How many bytes left for thus character?
var extraLength = null;
if (c >> 5 == 0x06) {
extraLength = 1;
} else if (c >> 4 == 0x0e) {
extraLength = 2;
} else if (c >> 3 == 0x1e) {
extraLength = 3;
} else if (c >> 2 == 0x3e) {
extraLength = 4;
} else if (c >> 1 == 0x7e) {
extraLength = 5;
} else {
continue;
}
// Do we have enough bytes in our data?
if (i+extraLength > len) {
var leftovers = array.slice(i-1);
// If there is an invalid byte in the leftovers we might want to
// continue from there.
for (; i < len; i++) if (array[i] >> 6 != 0x02) break;
if (i != len) continue;
// All leftover bytes are valid.
return {result: out, leftovers: leftovers};
}
// Remove the UTF-8 prefix from the char (res)
var mask = (1 << (8 - extraLength - 1)) - 1,
res = c & mask, nextChar, count;
for (count = 0; count < extraLength; count++) {
nextChar = array[i++];
// Is the char valid multibyte part?
if (nextChar >> 6 != 0x02) {break;};
res = (res << 6) | (nextChar & 0x3f);
}
if (count != extraLength) {
i--;
continue;
}
if (res <= 0xffff) {
out += String.fromCharCode(res);
continue;
}
res -= 0x10000;
var high = ((res >> 10) & 0x3ff) + 0xd800,
low = (res & 0x3ff) + 0xdc00;
out += String.fromCharCode(high, low);
}
return {result: out, leftovers: []};
}
Ceci retourne {result: "parsed string", leftovers: [list of invalid bytes at the end]}
si vous analysez la chaîne en morceaux.
EDIT: correction du problème trouvé par @unhammer.
Mettre à jour la réponse de @ Albert en ajoutant une condition pour emoji.
function Utf8ArrayToStr(array) {
var out, i, len, c;
var char2, char3, char4;
out = "";
len = array.length;
i = 0;
while(i < len) {
c = array[i++];
switch(c >> 4)
{
case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
// 0xxxxxxx
out += String.fromCharCode(c);
break;
case 12: case 13:
// 110x xxxx 10xx xxxx
char2 = array[i++];
out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F));
break;
case 14:
// 1110 xxxx 10xx xxxx 10xx xxxx
char2 = array[i++];
char3 = array[i++];
out += String.fromCharCode(((c & 0x0F) << 12) |
((char2 & 0x3F) << 6) |
((char3 & 0x3F) << 0));
break;
case 15:
// 1111 0xxx 10xx xxxx 10xx xxxx 10xx xxxx
char2 = array[i++];
char3 = array[i++];
char4 = array[i++];
out += String.fromCodePoint(((c & 0x07) << 18) | ((char2 & 0x3F) << 12) | ((char3 & 0x3F) << 6) | (char4 & 0x3F));
break;
}
return out;
}
Voici une solution qui gère tous les points de code Unicode, y compris les valeurs supérieures (4 octets), et prise en charge par tous les navigateurs modernes (IE et autres> 5.5). Il utilise decodeURIComponent (), mais PAS les fonctions d'échappement/unescape déconseillées:
function utf8_to_str(a) {
for(var i=0, s=''; i<a.length; i++) {
var h = a[i].toString(16)
if(h.length < 2) h = '0' + h
s += '%' + h
}
return decodeURIComponent(s)
}
Testé et disponible sur GitHub
Pour créer UTF-8 à partir d'une chaîne:
function utf8_from_str(s) {
for(var i=0, enc = encodeURIComponent(s), a = []; i < enc.length;) {
if(enc[i] === '%') {
a.Push(parseInt(enc.substr(i+1, 2), 16))
i += 3
} else {
a.Push(enc.charCodeAt(i++))
}
}
return a
}
Testé et disponible sur GitHub
Peut-être que l’utilisation de textDecoder sera suffisant.
Non pris en charge dans tous les navigateurs cependant. Mais cela pourrait suffire si vous utilisez un passage pour piétons ou tout autre cas d’utilisation pour lequel vous savez quel navigateur est utilisé.
var decoder = new TextDecoder('utf-8'),
decodedMessage;
decodedMessage = decoder.decode(message.data);
// String to Utf8 ByteBuffer
function strToUTF8(str){
return Uint8Array.from(encodeURIComponent(str).replace(/%(..)/g,(m,v)=>{return String.fromCodePoint(parseInt(v,16))}), c=>c.codePointAt(0))
}
// Utf8 ByteArray en chaîne
function UTF8toStr(ba){
return decodeURIComponent(ba.reduce((p,c)=>{return p+'%'+c.toString(16),''}))
}
Je pense que le moyen le plus simple serait d’utiliser une fonction js intégrée, decodeURI ()/encodeURI ().
function (usernameSent) {
var usernameEncoded = usernameSent; // Current value: utf8
var usernameDecoded = decodeURI(usernameReceived); // Decoded
// do stuff
}
En utilisant mon 1.6KB bibliothèque , vous pouvez faire
ToString(FromUTF8(Array.from(usernameReceived)))
C’est ce que j’ai trouvé après une recherche Google plus spécifique que le codage/décodage UTF-8. Donc, pour ceux qui recherchent une bibliothèque de conversion pour convertir entre les encodages, c'est parti.
https://github.com/inexorabletash/text-encoding
var uint8array = new TextEncoder().encode(str);
var str = new TextDecoder(encoding).decode(uint8array);
Coller depuis le repo readme
Tous les encodages de la spécification Encoding sont supportés:
utf-8 ibm866 iso-8859-2 iso-8859-3 iso-8859-4 iso-8859-5 iso-8859-6 iso-8859-7 iso-8859-8 iso-8859-8-i iso-8859- 10 iso-8859-13 iso-8859-14 iso-8859-15 iso-8859-16 koi8-r koi8-u fenêtres Macintosh-874 fenêtres-1250 fenêtres-1251 fenêtres-1252 fenêtres-1253 fenêtres-1254 fenêtres-1254 fenêtres -1256 fenêtres-1257 fenêtres-1258 x-mac-cyrillic gb18030 hz-gb-2312 big5 euc-jp iso-2022-jp shift_jis remplacement euc-kr utf-16be utf-16le x défini par l'utilisateur
(Certains codages peuvent être pris en charge sous d'autres noms, par exemple ascii, iso-8859-1, etc. Voir Codage pour des étiquettes supplémentaires pour chaque codage.)