zoukankan      html  css  js  c++  java
  • Javascript的坑之utf8编码


    1.原由

    使用javascript开发的时候发现,在部分第三方库中,对emoji的字符串进行UTF8编码出错。

    调查发现,javascript的string编码为UTF16(出处),而我们大部分时候使用的是UTF8。由于UTF16的设计,在大部分情况下编码javascript的字符串到UTF8都是没问题的。

    出问题的地方在剩下的那部分,我们先看UTF8和UTF16的异同。

     

    2.UTF8 and UTF16

    wiki上关于UTF8UTF16的资料已经很详细了。

    首先要理解的是无论是UTF8还是UTF16都是Unicode的一种形式。而Unicode其实就是一个字符表,范围为0~0x10FFFF。其间的每个数字是一个code point,所有的这些code point组成了Unicode的code space.

    而UTF8和UTF16则是code point的不同编码方式。

    UTF8使用变长的8-bit code units来表示code point。具体编码方式可以看wiki百科的说明。

    UTF16的code units则是16-bit.并且当code point在0~0xFFFF的范围内时,UTF16的code units在数字上等于code point的值。在U+10000到U+10FFFF范围时则需要进行编码。

     

    3.目标

    我们的目标是将javascript的字符串进行UTF8编码,而javascript字符串的编码方式为UTF16,因此我们的目的就是将UTF16转换为UTF8.

    转换的过程也很简单,UTF16->code points->UTF8

     

    4.问题所在

    上面我们可以看到,对于javascript的字符串,也就是UTF16编码的字符串,由于当code point的值在0~0xFFFF之间时, UTF16的编码值和code point上数值相同,并且生活中大部分情况下我们只会用到这个范围内的值,因此部分第三方库在进行UTF8编码时,直接省略了之前的UTF16->code points这一步。

    也就是说这个范围内的UTF16进行UTF8编码的时候可以直接调用javascript中String.charCodeAt()方法来获取每个UTF16字符code point的值,然后再根据UTF8编码的规则进行转换。

    然而String.charCodeAt()方法获取的值并不是和Unicode的code points完全相等,因此就会出错。

     

    5.解决方法

    如果是使用nodejs开发的话,可以直接使用utf8.js这个库。

    而在浏览器中则可根据wiki上的编码解码规则,使用String.charCodeAt()方法获得UTF16的值,然后解码为Unicode的code point,之后编码code point到UTF8即可。是比较简单的,而且可以借鉴utf8.js的写法。

    不过因为不同第三方库对字符串进行UTF8编码的情景不同,因此可能需要针对单独的库进行相应的调整,只要掌握了UTF8和UTF16的编码解码过程并不难。然而还是要鄙视一下这种自己造轮子结果漏气的行为。

  • 相关阅读:
    java.lang.OutOfMemoryError: Java heap space错误及处理办法
    JQuery 引发两次$(document.ready)事件
    用Jquery动态append方式加入标签时Css样式丢失的解决方法
    操作系统第6次实验报告:使用信号量解决进程互斥访问
    操作系统实验五:文件系统
    操作系统第4次实验报告:文件系统
    操作系统第三次实验报告:管道
    操作系统第2次实验报告:创建进程
    OS第1次实验报告:熟悉使用Linux命令和剖析ps命令
    第四次实验报告:使用Packet tracer理解RIP路由协议
  • 原文地址:https://www.cnblogs.com/zihuyishi/p/5068027.html
Copyright © 2011-2022 走看看