bat,ps1,vbs,js脚本运行乱码报错?原来是文本编码的问题!

bat,ps1,vbs,js脚本运行乱码报错?原来是文本编码的问题!

脚本类型 运行环境 推荐保存编码 备注
.js Node.js UTF-8 (无 BOM) 现代 Web 开发标准,绝不使用 BOM。
.js WScript (双击运行) ANSI (GBK) 这是 Windows 宿主环境,对 UTF-8 支持极差,用 ANSI 才能正常 WScript.Echo 中文。
.bat CMD 命令行 ANSI (GBK) 默认情况下,中文版 Windows 的 CMD 只能读懂 ANSI。如果强行存为 UTF-8,CMD 会报错或乱码。
.ps1 PowerShell 5.1 UTF-8 with BOM 老版本 PowerShell(Windows 自带的蓝底黑字版本)需要靠 BOM 来识别 UTF-8。
.ps1 PowerShell 7+ UTF-8 (无 BOM) 微软后来出的跨平台新版 PS(黑底),已经默认并推荐使用标准 UTF-8。
.vbs WScript / CScript ANSI (GBK)UTF-16 LE VBS 是非常古老的脚本,保存为 ANSI 是最稳妥的。如果在 Windows 记事本里,可以选择“ANSI”或“带有 BOM 的 UTF-16 LE” (记事本里叫 Unicode)。千万别用 UTF-8。

在 Windows 系统里,ANSI 根本不是一种特定的字符编码,而是一个“变色龙”。

简单来说,当你在 Windows 的记事本里选择保存为“ANSI”时,它的真实含义是:“使用当前电脑系统设置的默认本地语言编码”

ANSI 到底等于什么?因国而异!

因为 ANSI 是跟随系统语言变化的,所以同一份标着“ANSI”的文件,在不同国家的电脑上,底层真正使用的编码是完全不同的(Windows 术语称之为“代码页 Code Page”):

  • 在简体中文版 Windows 上: ANSI = GBK (代码页 936)
  • 在繁体中文版 Windows 上: ANSI = Big5 (代码页 950)
  • 在日本版 Windows 上: ANSI = Shift-JIS (代码页 932)
  • 在美国/英文版 Windows 上: ANSI = Windows-1252 (代码页 1252)

为什么英文不乱码,而中文会乱码?

这就是“乱码”现象的万恶之源:

  • 英文不乱码的原因: 无论是 GBK、Big5 还是 Windows-1252,它们都是从最基础的 ASCII 码扩展而来的。也就是说,它们的前 128 个字符(英文字母、数字、标点)的二进制数据完全一模一样。所以英文不管怎么换,都不会错。
  • 中文乱码的场景(跨国/跨系统): 假设你在中文版 Windows 上新建了一个文本文档,写了“你好”,并保存为 ANSI(系统默默用 GBK 把它存成了几个字节的数据)。 然后,你把这个文件发给了一个使用英文版 Windows 的外国朋友。他的系统双击打开这个文件时,发现编码是 ANSI,于是它理所当然地用 Windows-1252(英文系统的本地编码)去强行解读那几个字节的数据——结果就是,中文拼图被拼成了奇怪的欧洲字母或乱码(比如 ÄãºÃ)。

为什么微软要叫它ANSI?

ANSI 的全称是美国国家标准学会(American National Standards Institute)

在早期的 Windows 系统(Windows 3.1 和 Windows 95 时代),微软最初为了支持多种语言,引入了不同的代码页。当时英文默认的代码页是 Windows-1252,这个编码在一定程度上参考了 ANSI 组织制定的一份草案标准。于是,微软图省事,在系统里统一把“系统默认本地编码”的选项命名为了“ANSI”。

BOM是什么?

BOM 就是微软给文本文件强加的“私货标记”。

在现代的 Web 开发和编程中(包括你的 Hexo 博客、Node.js、JS、前端代码),BOM 是百害而无一利的。

BOM 最初是用来干嘛的?

在计算机底层,数据都是按“字节(Byte)”存储的。 像 UTF-16UTF-32 这种编码,一个字符需要用 2 个或 4 个字节来表示。那么问题来了:这几个字节在内存里,是先存高位还是先存低位呢?

  • Big-Endian(大端序):数据的高位字节存在前面(就像人头朝上站着)。
  • Little-Endian(小端序):数据的低位字节存在前面(就像人倒立着)。

为了告诉计算机这个文件到底是“站着”还是“倒立”的,Unicode 标准规定,在文件的最开头加上一个特殊的隐形字符(代码是 U+FEFF)。计算机一读到这个字符,就知道该怎么去解析后面的字节了。这个隐形字符,就是 BOM。

为什么在 UTF-8 里,BOM 变成了“毒瘤”?

请注意:UTF-8 根本不需要 BOM!

UTF-8 的设计非常巧妙,它的字节顺序是固定的(每次按顺序读 1 到 4 个字节),不存在“大端”或“小端”的问题。所以在国际标准中,UTF-8 文件是不推荐加 BOM 的

那为什么会有 “UTF-8 with BOM” 这种东西呢? 这又要怪微软了。

在早期,Windows 系统的默认编码是 ANSI。当 Windows 自带的“记事本”打开一个文件时,它不知道这到底是 ANSI 还是 UTF-8。为了偷懒,微软做了一个决定:

只要是用记事本保存的 UTF-8 文件,都在开头塞进去 3 个字节的 BOM(十六进制是 EF BB BF)。下次打开时,只要看到这 3 个字节,记事本就知道它是 UTF-8 了

BOM 是怎么让你的代码崩溃的?

因为这 3 个字节(EF BB BF)是隐形的(专业叫法叫“零宽无断空白字符”),你在编辑器里根本看不见它,但计算机程序在读取时却会被它坑惨。

现代的编程环境(Linux、Mac、Node.js、Web 浏览器)默认所有文件都是标准的 UTF-8,它们不认识也不理会 BOM 作为标记的作用,而是把它当成普通的文本内容读进去

这会导致非常多诡异的 Bug,比如JS 脚本报错: 如果你的 .js 文件带了 BOM,Node.js 去运行它的第一行代码时,会发现前面多了一串无法识别的乱码字符,直接报 SyntaxError(语法错误),代码直接罢工。


bat,ps1,vbs,js脚本运行乱码报错?原来是文本编码的问题!
https://lvlele.top/205bat,ps1,vbs,js脚本运行乱码报错原来是文本编码的问题/
作者
吕了了
发布于
2026年5月19日
许可协议