В моем коде JavaScript мне нужно составить сообщение на сервер в следующем формате:
<size in bytes>CRLF
<data>CRLF
Пример:
3
foo
Данные могут содержать символы Юникода. Мне нужно отправить их как UTF-8.
Я ищу наиболее кроссбраузерный способ вычисления длины строки в байтах в JavaScript.
Я пробовал это, чтобы составить свою полезную нагрузку:
return unescape(encodeURIComponent(str)).length + "\n" + str + "\n"
Но он не дает мне точных результатов для старых браузеров (или, может быть, строк в этих браузерах в UTF-16?).
Какие-нибудь подсказки?
Обновить:
Пример: длина строки в байтах ЭЭХ! Naïve?
в UTF-8 составляет 15 байтов, но некоторые браузеры вместо этого сообщают 23 байта.
javascript
unicode
Александр Гладыш
источник
источник
Ответы:
В JavaScript нет возможности сделать это изначально.(См . Ответ Риккардо Галли о современном подходе.)Для исторической справки или для тех случаев, когда API-интерфейсы TextEncoder все еще недоступны .
Если вы знаете кодировку символов, вы можете рассчитать ее самостоятельно.
encodeURIComponent
предполагает UTF-8 в качестве кодировки символов, поэтому, если вам нужна эта кодировка, вы можете сделать,Это должно работать, потому что UTF-8 кодирует многобайтовые последовательности. Первый закодированный байт всегда начинается либо со старшего бита нуля для однобайтовой последовательности, либо с байта, первая шестнадцатеричная цифра которого равна C, D, E или F. Второй и последующие байты - это те, у которых первые два бита равны 10. Это дополнительные байты, которые вы хотите посчитать в UTF-8.
Таблица в википедии делает понятнее
Если вместо этого вам нужно понять кодировку страницы, вы можете использовать этот трюк:
источник
lengthInUtf8Bytes
функция возвращает 5 для символов, отличных от BMP, какstr.length
для этих возвратов 2. Я напишу измененную версию этой функции в разделе ответов.encodeURIComponent('🍀')
есть'%F0%9F%8D%80'
.Прошли годы, и теперь вы можете делать это изначально
Обратите внимание, что он еще не поддерживается IE (или Edge) (для этого вы можете использовать полифилл ).
Документация MDN
Стандартные характеристики
источник
TextEncode
поддерживает только utf-8 с Chrome 53.Вот гораздо более быстрая версия, в которой не используются ни регулярные выражения, ни encodeURIComponent () :
Вот сравнение производительности .
Он просто вычисляет длину в UTF8 каждой кодовой точки Unicode, возвращаемой charCodeAt () (на основе описаний в Википедии UTF8 и суррогатных символов UTF16).
Он соответствует RFC3629 (где символы UTF-8 имеют длину не более 4 байтов).
источник
Для простой кодировки UTF-8 с немного лучшей совместимостью, чем
TextEncoder
Blob, подойдет. Однако не будет работать в очень старых браузерах.источник
Эта функция вернет размер в байтах любой строки UTF-8, которую вы ей передали.
Источник
источник
ユーザーコード
длина в байтах всегда 21, я тестировал это на разных инструментах; будьте любезны с вашими комментариями;)Еще один очень простой подход с использованием
Buffer
(только для NodeJS):источник
Buffer.byteLength(string, 'utf8')
.Мне потребовалось время, чтобы найти решение для React Native, поэтому я помещу его здесь:
Сначала установите
buffer
пакет:Затем используйте метод узла:
источник
Собственно, в чем дело, разобрался. Для работы кода на странице
<head>
должен быть такой тег:Или, как предлагается в комментариях, если сервер отправляет HTTP-
Content-Encoding
заголовок, он также должен работать.Тогда результаты из разных браузеров будут согласованы.
Вот пример:
Примечание: я подозреваю, что указание любой (точной) кодировки решит проблему с кодировкой. Просто совпадение, что мне нужен UTF-8.
источник
unescape
Функция JavaScript не должна быть использована для декодирования Uniform Resource идентификаторов (URI).unescape
действительно никогда не следует использовать для декодирования URI. Однако для преобразования текста в UTF-8 он отличноunescape(encodeURIComponent(...)).length
всегда рассчитывает правильную длину с учетом или безmeta http-equiv ... utf8
. Без спецификации кодировки некоторые браузеры могли просто иметь другой текст (после кодирования байтов документа в фактический текст html), длину которого они вычисляли. Это можно легко проверить, напечатав не только длину, но и сам текст.Вот независимый и эффективный метод подсчета байтов UTF-8 в строке.
Обратите внимание, что метод может вызвать ошибку, если входная строка имеет неправильный формат UCS-2.
источник
В NodeJS
Buffer.byteLength
это метод специально для этой цели:Обратите внимание, что по умолчанию метод предполагает, что строка находится в кодировке UTF-8. Если требуется другая кодировка, передайте ее как второй аргумент.
источник
strLengthInBytes
просто зная «количество» символов в строке? то естьvar text = "Hello World!; var text_length = text.length; // pass text_length as argument to some method?
. И, для справки, повторноBuffer
- я только что наткнулся на этот ответ, в котором обсуждается,new Blob(['test string']).size
и в узлеBuffer.from('test string').length
. Может быть, это кому-то тоже поможет?Это будет работать для символов BMP и SIP / SMP.
источник
Вы можете попробовать это:
Меня устраивает.
источник