最近在做一个前后端分离的项目,服务端是用 Node 写的。需求大概是这样的:在前端界面点击按钮,触发下载一份文件到本地,需要特别提到的是文件中包含中文字符串。
一看这需求,心想这还不 easy 吗?暗戳戳地写了个接口,download 就实现了。打开文件一看,wtf,中文怎么都乱码了!!!
不能忍,回想这一整个流程,似乎并没有对字符编码进行处理,隐隐发现出现问题的地方了。于是,在流程的每个涉及到字符编码的地方,都强行用 utf-8 去处理。
读文件流:
let input = fs.createReadStream(path)
input.setEncoding('utf8')
复制代码
设置 Content-Type:
res.setHeader('Content-Type', 'text/plain;charset = utf-8')
复制代码
设置输出流:
res.write(data, 'utf8')
复制代码
这一套组合拳打出来以后效果立竿见影,下载的文件中文都能正常显示了。
拉到文件底部,咦,文件怎么被截断了,还有一些内容不见了,跑去哪了啊。
回来又定睛一看,可能 Content-Length 出了问题。果不其然,上面的 data 是我们输出的字符串,我用 data.length 来获取它的长度,中文都被当成一个字节处理了。然而中文可能是三四个字节呀!正确的计算长度需要用 Buffer 类来获取。
res.setHeader('Content-Length', Buffer.byteLength(data))
复制代码
啊,好烦。我这么帅,为什么要吃 Node 的苦。
祝大家 520 快乐?!