Dans mon code JavaScript, j'ai besoin de composer un message au serveur dans ce format:
<size in bytes>CRLF
<data>CRLF
Exemple:
3
foo
Les données peuvent contenir des caractères Unicode. Je dois les envoyer en UTF-8.
Je recherche le moyen le plus polyvalent pour calculer la longueur de la chaîne en octets en JavaScript.
J'ai essayé ceci pour composer ma charge utile:
return unescape(encodeURIComponent(str)).length + "\n" + str + "\n"
Mais cela ne me donne pas de résultats précis pour les anciens navigateurs (ou peut-être les chaînes de ces navigateurs en UTF-16?).
Des indices?
Mettre à jour:
Exemple: la longueur en octets de la chaîne ЭЭХ! Naïve?
en UTF-8 est de 15 octets, mais certains navigateurs rapportent 23 octets à la place.
javascript
unicode
Alexandre Gladysh
la source
la source
Réponses:
Il n'y a aucun moyen de le faire en JavaScript de manière native.(Voir la réponse de Riccardo Galli pour une approche moderne.)Pour référence historique ou lorsque les API TextEncoder ne sont toujours pas disponibles .
Si vous connaissez le codage des caractères, vous pouvez le calculer vous-même.
encodeURIComponent
suppose UTF-8 comme encodage de caractères, donc si vous avez besoin de cet encodage, vous pouvez faire,Cela devrait fonctionner en raison de la façon dont UTF-8 encode les séquences multi-octets. Le premier octet codé commence toujours par soit un bit haut de zéro pour une séquence à un octet, soit un octet dont le premier chiffre hexadécimal est C, D, E ou F.Le deuxième octet et les suivants sont ceux dont les deux premiers bits sont 10 Ce sont les octets supplémentaires que vous voulez compter en UTF-8.
La table dans wikipedia le rend plus clair
Si à la place vous avez besoin de comprendre l'encodage de la page, vous pouvez utiliser cette astuce:
la source
lengthInUtf8Bytes
fonction renvoie 5 pour les caractères non BMP commestr.length
pour ces retours 2. J'écrirai une version modifiée de cette fonction dans la section des réponses.encodeURIComponent('🍀')
est'%F0%9F%8D%80'
.Les années ont passé et de nos jours vous pouvez le faire nativement
Notez qu'il n'est pas encore pris en charge par IE (ou Edge) (vous pouvez utiliser un polyfill pour cela).
Documentation MDN
Spécifications standard
la source
TextEncode
prend en charge uniquement utf-8 depuis Chrome 53.Voici une version beaucoup plus rapide, qui n'utilise pas d'expressions régulières, ni encodeURIComponent () :
Voici une comparaison des performances .
Il calcule simplement la longueur en UTF8 de chaque codet Unicode retourné par charCodeAt () (basé sur les descriptions de wikipedia de UTF8 caractères de substitution et UTF16).
Il suit la RFC3629 (où les caractères UTF-8 font au plus 4 octets de long).
la source
Pour un encodage UTF-8 simple, avec une compatibilité légèrement meilleure que
TextEncoder
, Blob fait l'affaire. Ne fonctionnera pas dans les très vieux navigateurs.la source
Cette fonction renverra la taille d'octet de toute chaîne UTF-8 que vous lui passez.
La source
la source
ユーザーコード
longueur en octets est toujours de 21, je l'ai testé sur différents outils; soyez plus gentil avec vos commentaires;)Une autre approche très simple utilisant
Buffer
(uniquement pour NodeJS):la source
Buffer.byteLength(string, 'utf8')
.Il m'a fallu un certain temps pour trouver une solution pour React Native donc je vais la mettre ici:
Installez d'abord le
buffer
package:Ensuite, utilisez la méthode du nœud:
la source
En fait, j'ai compris ce qui ne va pas. Pour que le code fonctionne, la page
<head>
doit avoir cette balise:Ou, comme suggéré dans les commentaires, si le serveur envoie HTTP
Content-Encoding
tête , cela devrait également fonctionner.Ensuite, les résultats de différents navigateurs sont cohérents.
Voici un exemple:
Remarque: je soupçonne que la spécification d' un encodage (précis) résoudrait le problème d'encodage. C'est juste une coïncidence que j'ai besoin d'UTF-8.
la source
unescape
fonction JavaScript ne doit pas être utilisée pour décoder des URI (Uniform Resource Identifiers).unescape
ne doit en effet jamais être utilisé pour décoder les URI. Cependant, pour convertir du texte en UTF-8, cela fonctionne bienunescape(encodeURIComponent(...)).length
calcule toujours la longueur correcte avec ou sansmeta http-equiv ... utf8
. Sans une spécification de codage, certains navigateurs pourraient simplement avoir un texte différent (après avoir codé les octets du document en texte html réel) dont ils ont calculé la longueur. On pourrait tester cela facilement, en imprimant non seulement la longueur, mais aussi le texte lui-même.Voici une méthode indépendante et efficace pour compter les octets UTF-8 d'une chaîne.
Notez que la méthode peut générer une erreur si une chaîne d'entrée est malformée UCS-2
la source
Dans NodeJS,
Buffer.byteLength
est une méthode spécifiquement à cet effet:Notez que par défaut, la méthode suppose que la chaîne est en codage UTF-8. Si un codage différent est requis, passez-le comme deuxième argument.
la source
strLengthInBytes
simplement en connaissant le «nombre» de caractères dans la chaîne? ievar text = "Hello World!; var text_length = text.length; // pass text_length as argument to some method?
. Et, juste pour la référence, reBuffer
- Je viens suis tombé sur cette réponse qui traitenew Blob(['test string']).size
et, dans le nœud,Buffer.from('test string').length
. Peut-être que cela aidera certaines personnes aussi?Cela fonctionnerait pour les caractères BMP et SIP / SMP.
la source
Vous pouvez essayer ceci:
Ça marche pour moi.
la source