[NodeJs系列]聊一聊BOM
最近在看Node源码的时候,偶然间,看到如下函数:
/**
* Remove byte order marker. This catches EF BB BF (the UTF-8 BOM)
* because the buffer-to-string conversion in `fs.readFileSync()`
* translates it to FEFF, the UTF-16 BOM.
*/
function stripBOM(content) {
if (content.charCodeAt(0) === 0xFEFF) {
content = content.slice(1);
}
return content;
}
对于函数的功能,注释写的很清楚了-用于清除字节序标识符(BOM)。
对于BOM,相信大多数人对其即陌生又熟悉,我们在各大IDE中常常见到它的身影,但要真的把它解释清除,却有点力不从心。故此,笔者利用闲暇之余搜索资料整理成文,如果错漏,还望提点!
字节序
在解释BOM之前,我们不得不提到字节序。
在古时,我们的很多书刊保有从左到右的排版的习惯。即使是今天,某些国家的文字读序依旧存在差异。计算机世界也是如此。
我们把多字节排练的顺序叫做字节序。
这里我们通过一个例子展开说明(本例来自:“字节序”是个什么鬼?):
给定两个分别需要4个字节存储的整数,为了方便说明,使用16进制表示这两个数,即0x12345678和0x11223344。对于如何存储,有人提了两个方案:
方案一:

方案二:

对于方案一,高位字节在存储在高位地址,低位字节在低位地址,我们称之为大端(Big endian)字节序。方案二把低位字节在前,高位字节在后,我们把这种顺序叫做小端(Little endian)字节序。
BOM
对于人类而言,字节序也许并不是问题。比如从右往左读"字节序",聪明如你们,会发现“序节字”根本语义不通,可以轻松的找到解决之道。但对于计算机而言,它不明白什么是语义,也没法联系上下文。它只能按照给定的指令去读取字节。如果是大端字节序,先读到的就是高位字节,后读到的就是低位字节。小端字节序正好相反。
所以对于计算机而言,我们需要一种方法去标识字节序,以防乱码的出现。BOM就是一种用于标识的unicode字符,它常被用来当做标示以UTF-8、UTF-16或UTF-32为编码的文件
对于UTF-16和UTF-32而言,因为他们分别使用2个字节和4个字节编码Unicode字符,对于多字节编码,BOM的存在显然很有必要。此时BOM被放置为文件或字符串流的第一个字符,如果标识符为U+FFFE则表示大端字节序,如果标识符为U+FEFF则表示小端字节序。
那既然BOM是用于标示字节序的,那为什么还要把它删除呢?这里就不得不提一下UTF-8了。
UTF-8是一种可变字节长度的编码方式(最小1字节,最大4字节),也就是说UTF-8可以根据数据大小来决定要存储的字节数。它的编码方式与其他两者不同,无需使用BOM。
UTF-8在首字节标识了字节的个数。如果首字节以0开头,则代表单字节编码,如果以110开头者表示该字节为两个字节中的第一个字节,以此类推。除了单字节外,多字节UTF-8码的后续字节均以10开头。
所以1~4字节UTF-8编码看起来是这样的:
0xxxxxxx
110xxxxx 10xxxxxx
1110xxxx 10xxxxxx 10xxxxxx
11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
```
So BOM 在UTF-8编码中是非必须的,在类Unix系统(大量使用文本文件,用于文件格式,用于进程间通信)中,这种做法(插入BOM)是不被建议采用,因为它会妨碍到如解译器脚本开头的Shebang等的正确处理,但是许多视窗程序(包含记事本)会需要添加字节顺序标记到UTF-8文件。
参考
来源:https://segmentfault.com/a/1190000017547441
[NodeJs系列]聊一聊BOM的更多相关文章
- NodeJS系列~目录
回到占占推荐博客索引 Node.js官网对它的阐述 Node.js is a platform built on Chrome's JavaScript runtime for easily buil ...
- NodeJS系列-部署
NodeJS系列-部署 NodeJS我就不介绍了,被标题吸引进来的人可以看这个链接,了解NodeJS.下来就开始关于NodeJS开发的指南. NodeJS可以部署的平台有Windows,Unix,iO ...
- [NodeJs系列][译]理解NodeJs中的Event Loop、Timers以及process.nextTick()
译者注: 为什么要翻译?其实在翻译这篇文章前,笔者有Google了一下中文翻译,看的不是很明白,所以才有自己翻译的打算,当然能力有限,文中或有错漏,欢迎指正. 文末会有几个小问题,大家不妨一起思考一下 ...
- javascript系列-class8.BOM
1.浏览器对象模型( browser object model ) 什么是BOM? 提起BOM就不得不提起JavaScript的构成.ECMAScript为JavaScript的核心,但是要 ...
- NodeJS系列~第一个小例子,实现了request.querystring功能
返回目录 百度百科上: Node.js是一套用来编写高性能网络服务器的JavaScript工具包,一系列的变化由此开始,在Node中,Http是首要的.Node为创建http服务器作了优化,所以在网上 ...
- NodeJS系列~第三个小例子,NodeJs与Redis实现高并发的队列存储
返回目录 众所周知 redis量个强大的缓存组件,可以部署在win32和linux环境之上,它有五大存储结构,其中有一种为列表list,它可以实现quene和stack的功能,即队列和堆栈的功能. r ...
- NodeJS系列~第四个小例子,NodeJs处理Get请求和Post请求
返回目录 说在前 对于HTTP请求来说,我们通常使用的是Get和Post,除此之外还有put,delete等,而对于get来说,比较lightweight,只是对字符串的传输,它会被添加到URL地址里 ...
- Nodejs系列-01-开篇
1.解决什么问题 1. 并发连接 举个例子,想象一个场景,我们在银行排队办理业务,我们看看下面两个模型. (1)系统线程模型: 这种模型的问题显而易见,服务端只有一个线程,并发请求(用户)到达只能处理 ...
- nodejs系列(一)安装和介绍
一.安装nodejs http://www.nodejs.org/download/.进入release/选择想要安装的文件,win下安装选择mis和exe的比较方便,安装完毕重新打开cmd命令行,p ...
随机推荐
- CentOS查看和修改PATH环境变量的方法
查看PATH:echo $PATH以添加mongodb server为列修改方法一:export PATH=/usr/local/mongodb/bin:$PATH//配置完后可以通过echo $PA ...
- JAVA静态方法是否可以被继承
结论:java中静态属性和静态方法可以被继承,但是没有被重写(overwrite)而是被隐藏.原因:1). 静态方法和属性是属于类的,调用的时候直接通过类名.方法名完成对,不需要继承机制及可以调用.如 ...
- 利用freemarker生成word,word另存为xml文件的标签解析
http://wenku.baidu.com/link?url=YxTZWVP3ssO-e_Br3LIZVq2xOQnqaSz8gLPiRUDN8NIR_wX2-Z25OqwbVn5kXqGiOFYU ...
- jsvnadmin访问一直登陆 找不到用户
报错:AH01618: user zhangsan not found: /svn/hangzhi 在svnadmin控制台上将用户分好组,不然即使有账户也登不上
- Mysql 中需不需要commit
摘自:https://blog.csdn.net/zzyly1/article/details/81003122 mysql在进行增删改操作的时候需不需要commit,这得看你的存储引擎, 如果是不支 ...
- oracle系统视图V$
--数据字典表select * from v$fixed_table;select * from v$fixed_view_definition;select * from dictionary; - ...
- HiMall 3接口鉴权参考
签名算法 为了防止API调用过程中被黑客恶意篡改,调用任何一个API都需要携带签名,HOP服务端会根据请求参数,对签名进行验证,签名不合法的请求将会被拒绝.TOP目前支持的签名算法只有一种:MD5(s ...
- TCP中三次挥手四次握手
1.TCP连接 手机能够使用联网功能是因为手机底层实现了TCP/IP协议,可以使手机终端通过无线网络建立TCP连接.TCP协议可以对上层网络提供接口,使上层网络数据的传输建立在“无差别”的网络之上. ...
- Hibernate——简单的增、删、改、查操作
思路: 1.导入hibernate jar包 2.导入mysql jar包 3.创建数据库 4.创建java实体类 5.编写hibernate.cfg.xml配置文件 6.编写dao类 目录: 数据表 ...
- Kubernetes网络隔离NetworkPolicy
Kubernetes要求集群中所有pod,无论是节点内还是跨节点,都可以直接通信,或者说所有pod工作在同一跨节点网络,此网络一般是二层虚拟网络,称为pod网络.在安装引导kubernetes时,由选 ...