In meinem JavaScript-Code muss ich eine Nachricht an den Server in diesem Format verfassen:
<size in bytes>CRLF
<data>CRLF
Beispiel:
3
foo
Die Daten können Unicode-Zeichen enthalten. Ich muss sie als UTF-8 senden.
Ich suche nach der browserübergreifendsten Methode, um die Länge der Zeichenfolge in Byte in JavaScript zu berechnen.
Ich habe dies versucht, um meine Nutzlast zusammenzustellen:
return unescape(encodeURIComponent(str)).length + "\n" + str + "\n"
Aber es gibt mir keine genauen Ergebnisse für die älteren Browser (oder vielleicht die Zeichenfolgen in diesen Browsern in UTF-16?).
Irgendwelche Hinweise?
Aktualisieren:
Beispiel: Die Länge der Zeichenfolge ЭЭХ! Naïve?
in UTF-8 in Byte beträgt 15 Byte. Einige Browser melden jedoch stattdessen 23 Byte.
javascript
unicode
Alexander Gladysh
quelle
quelle
Antworten:
Es gibt keine Möglichkeit, dies nativ in JavaScript zu tun.(Siehe Riccardo Gallis Antwort für einen modernen Ansatz.)Zur historischen Bezugnahme oder wenn TextEncoder-APIs noch nicht verfügbar sind .
Wenn Sie die Zeichenkodierung kennen, können Sie sie jedoch selbst berechnen.
encodeURIComponent
nimmt UTF-8 als Zeichencodierung an. Wenn Sie diese Codierung benötigen, können Sie Folgendes tun:Dies sollte aufgrund der Art und Weise funktionieren, wie UTF-8 Mehrbyte-Sequenzen codiert. Das erste codierte Byte beginnt immer entweder mit einem hohen Bit von Null für eine einzelne Bytesequenz oder mit einem Byte, dessen erste hexadezimale Ziffer C, D, E oder F ist. Das zweite und nachfolgende Byte sind diejenigen, deren erste zwei Bits 10 sind Dies sind die zusätzlichen Bytes, die Sie in UTF-8 zählen möchten.
Die Tabelle in Wikipedia macht es klarer
Wenn Sie stattdessen die Seitencodierung verstehen müssen, können Sie diesen Trick verwenden:
quelle
lengthInUtf8Bytes
Funktion gibt 5 für Nicht-BMP-Zeichen zurück, wiestr.length
für diese Rückgaben 2. Ich werde eine modifizierte Version dieser Funktion in den Antwortabschnitt schreiben.encodeURIComponent('🍀')
ist'%F0%9F%8D%80'
.Jahre vergingen und heutzutage kann man es nativ machen
Beachten Sie, dass es vom IE (oder Edge) noch nicht unterstützt wird (Sie können dafür eine Polyfüllung verwenden ).
MDN-Dokumentation
Standardspezifikationen
quelle
TextEncode
unterstützt nur utf-8 seit Chrome 53.Hier ist eine viel schnellere Version, die weder reguläre Ausdrücke noch encodeURIComponent () verwendet :
Hier ist ein Leistungsvergleich .
Es berechnet lediglich die Länge aller von charCodeAt () zurückgegebenen Unicode-Codepunkte in UTF8 (basierend auf den Wikipedia-Beschreibungen von UTF8 und UTF16-Ersatzzeichen ).
Es folgt RFC3629 (wobei UTF-8-Zeichen höchstens 4 Byte lang sind).
quelle
Für eine einfache UTF-8-Codierung mit etwas besserer Kompatibilität als
TextEncoder
Blob ist dies der Trick. Funktioniert jedoch nicht in sehr alten Browsern.quelle
Diese Funktion gibt die Bytegröße aller UTF-8-Zeichenfolgen zurück, die Sie an sie übergeben.
Quelle
quelle
ユーザーコード
Länge in Bytes ist immer 21, ich habe es auf verschiedenen Tools getestet; Sei freundlicher mit deinen Kommentaren;)Ein weiterer sehr einfacher Ansatz
Buffer
(nur für NodeJS):quelle
Buffer.byteLength(string, 'utf8')
.Ich habe eine Weile gebraucht , um eine Lösung für React Native zu finden, also werde ich sie hier einfügen :
Installieren Sie zuerst das
buffer
Paket:Verwenden Sie dann die Knotenmethode:
quelle
Eigentlich habe ich herausgefunden, was los ist. Damit der Code funktioniert, sollte die Seite
<head>
dieses Tag haben:Wenn der Server einen HTTP-
Content-Encoding
Header sendet , sollte dies auch funktionieren , wie in den Kommentaren vorgeschlagen .Dann sind die Ergebnisse von verschiedenen Browsern konsistent.
Hier ist ein Beispiel:
Hinweis: Ich vermute, dass die Angabe einer (genauen) Codierung das Codierungsproblem beheben würde. Es ist nur ein Zufall, dass ich UTF-8 brauche.
quelle
unescape
JavaScript-Funktion sollte nicht zum Dekodieren von URI (Uniform Resource Identifiers) verwendet werden.unescape
sollte in der Tat niemals zum Dekodieren von URIs verwendet werden. Um Text in UTF-8 zu konvertieren, funktioniert es jedoch einwandfreiunescape(encodeURIComponent(...)).length
berechnet immer die richtige Länge mit oder ohnemeta http-equiv ... utf8
. Ohne eine Codierungsspezifikation könnten einige Browser einfach einen anderen Text haben (nachdem die Bytes des Dokuments in tatsächlichen HTML-Text codiert wurden), dessen Länge sie berechnet haben. Man könnte dies leicht testen, indem man nicht nur die Länge, sondern auch den Text selbst druckt.Hier ist eine unabhängige und effiziente Methode zum Zählen von UTF-8-Bytes einer Zeichenfolge.
Beachten Sie, dass die Methode möglicherweise einen Fehler auslöst, wenn eine Eingabezeichenfolge fehlerhaft ist
quelle
In NodeJS
Buffer.byteLength
ist eine Methode speziell für diesen Zweck:Beachten Sie, dass die Methode standardmäßig davon ausgeht, dass die Zeichenfolge in UTF-8-Codierung vorliegt. Wenn eine andere Codierung erforderlich ist, übergeben Sie diese als zweites Argument.
quelle
strLengthInBytes
nur zu berechnen, indem man die Anzahl der Zeichen in der Zeichenfolge kennt? dhvar text = "Hello World!; var text_length = text.length; // pass text_length as argument to some method?
. Und nur als Referenz,Buffer
ich bin gerade auf diese Antwort gestoßen , die diskutiertnew Blob(['test string']).size
und im Knoten ,Buffer.from('test string').length
. Vielleicht helfen diese auch einigen Menschen?Dies würde für BMP- und SIP / SMP-Zeichen funktionieren.
quelle
Sie können dies versuchen:
Für mich geht das.
quelle