En mi código JavaScript, necesito redactar un mensaje al servidor en este formato:
<size in bytes>CRLF
<data>CRLF
Ejemplo:
3
foo
Los datos pueden contener caracteres Unicode. Necesito enviarlos como UTF-8.
Estoy buscando la forma más cruzada de navegador para calcular la longitud de la cadena en bytes en JavaScript.
Intenté esto para componer mi carga útil:
return unescape(encodeURIComponent(str)).length + "\n" + str + "\n"
Pero no me da resultados precisos para los navegadores más antiguos (o, ¿tal vez las cadenas de esos navegadores en UTF-16?).
¿Alguna pista?
Actualizar:
Ejemplo: la longitud en bytes de la cadena ЭЭХ! Naïve?
en UTF-8 es de 15 bytes, pero algunos navegadores reportan 23 bytes en su lugar.
javascript
unicode
Alejandro Gladysh
fuente
fuente
Respuestas:
No hay forma de hacerlo en JavaScript de forma nativa.(Vea la respuesta de Riccardo Galli para un enfoque moderno).Para referencia histórica o donde las API de TextEncoder aún no están disponibles .
Si conoce la codificación de caracteres, puede calcularla usted mismo.
encodeURIComponent
asume UTF-8 como la codificación de caracteres, por lo que si necesita esa codificación, puede hacerlo,Esto debería funcionar debido a la forma en que UTF-8 codifica secuencias de varios bytes. El primer byte codificado siempre comienza con un bit alto de cero para una secuencia de un solo byte, o un byte cuyo primer dígito hexadecimal es C, D, E o F. El segundo y subsiguientes bytes son aquellos cuyos primeros dos bits son 10 Esos son los bytes adicionales que desea contar en UTF-8.
La tabla en wikipedia lo aclara
Si, en cambio, necesita comprender la codificación de la página, puede usar este truco:
fuente
lengthInUtf8Bytes
función devuelve 5 para caracteres que no son BMP comostr.length
para estos devuelve 2. Escribiré una versión modificada de esta función en la sección de respuestas.encodeURIComponent('🍀')
es'%F0%9F%8D%80'
.Pasaron los años y hoy en día puedes hacerlo de forma nativa
Tenga en cuenta que aún no es compatible con IE (o Edge) (puede usar un polyfill para eso).
Documentación MDN
Especificaciones estándar
fuente
TextEncode
solo admite utf-8 desde Chrome 53.Aquí hay una versión mucho más rápida, que no usa expresiones regulares, ni encodeURIComponent () :
Aquí hay una comparación de rendimiento .
Simplemente calcula la longitud en UTF8 de cada punto de código Unicode devuelto por charCodeAt () (según las descripciones de wikipedia de caracteres sustitutos UTF8 y UTF16).
Sigue a RFC3629 (donde los caracteres UTF-8 tienen una longitud máxima de 4 bytes).
fuente
Para la codificación UTF-8 simple, con una compatibilidad ligeramente mejor que
TextEncoder
, Blob hace el truco. Sin embargo, no funcionará en navegadores muy antiguos.fuente
Esta función devolverá el tamaño en bytes de cualquier cadena UTF-8 que le pase.
Fuente
fuente
ユーザーコード
longitud incorrecta en bytes es siempre 21, lo probé en diferentes herramientas; sea más amable con sus comentarios;)Otro enfoque muy simple usando
Buffer
(solo para NodeJS):fuente
Buffer.byteLength(string, 'utf8')
.Me tomó un tiempo encontrar una solución para React Native, así que la pondré aquí:
Primero instale el
buffer
paquete:Luego use el método de nodo:
fuente
De hecho, descubrí lo que estaba mal. Para que el código funcione, la página
<head>
debe tener esta etiqueta:O, como se sugiere en los comentarios, si el servidor envía un
Content-Encoding
encabezado HTTP , también debería funcionar.Entonces los resultados de diferentes navegadores son consistentes.
Aquí hay un ejemplo:
Nota: sospecho que especificar cualquier codificación (precisa) solucionaría el problema de codificación. Es solo una coincidencia que necesite UTF-8.
fuente
unescape
función de JavaScript no debe usarse para decodificar identificadores uniformes de recursos (URI).unescape
hecho nunca debería usarse para decodificar URI. Sin embargo, para convertir texto a UTF-8 funciona bienunescape(encodeURIComponent(...)).length
siempre calcula la longitud correcta con o sinmeta http-equiv ... utf8
. Sin una especificación de codificación, algunos navegadores podrían simplemente tener un texto diferente (después de codificar los bytes del documento en texto html real) cuya longitud calcularon. Se podría probar esto fácilmente, imprimiendo no solo la longitud, sino también el texto en sí.Aquí hay un método independiente y eficiente para contar bytes UTF-8 de una cadena.
Tenga en cuenta que el método puede arrojar un error si una cadena de entrada tiene un formato UCS-2 incorrecto
fuente
En NodeJS,
Buffer.byteLength
es un método específicamente para este propósito:Tenga en cuenta que, de forma predeterminada, el método asume que la cadena está en codificación UTF-8. Si se requiere una codificación diferente, pásala como segundo argumento.
fuente
strLengthInBytes
simplemente conociendo el 'recuento' de caracteres dentro de la cadena? es decirvar text = "Hello World!; var text_length = text.length; // pass text_length as argument to some method?
. Y, apenas para la referencia, reBuffer
- Acabo de encontrar esta respuesta la que se explicanew Blob(['test string']).size
y, en nodo,Buffer.from('test string').length
. ¿Quizás estos también ayuden a algunas personas?Esto funcionaría para caracteres BMP y SIP / SMP.
fuente
Puedes probar esto:
Esto funciona para mi.
fuente