1. 检查服务器操作系统Locale与默认编码
步骤:用SSH登录
韩国服务器(例如Ubuntu/CentOS)。
- 查看当前locale:执行命令:locale
- 列出可用locale:locale -a
- 若未显示UTF-8,例如缺少en_US.UTF-8或ko_KR.UTF-8,则生成:sudo locale-gen en_US.UTF-8 或 sudo localedef -i ko_KR -f UTF-8 ko_KR.UTF-8(基于发行版)。
- 临时设置:export LANG=en_US.UTF-8; export LC_ALL=en_US.UTF-8。若为systemd服务,编辑对应的.service,添加 Environment=LANG=en_US.UTF-8 并重启服务。
2. 确保文本文件与脚本保存为UTF-8无BOM
小步骤:在本地开发时选用编辑器保存为UTF-8(无BOM)。
- 检查文件编码:file -i filename 或 iconv -f 原编码 -t utf-8 文件 > /dev/null。
- 转换编码:iconv -f GBK -t UTF-8 old.php > new.php(测试无误后替换)。Git上可用 .gitattributes 强制文本编码。
3. Web服务器(Nginx/Apache)头部设置
Nginx:在server或http块中加入:add_header Content-Type "text/html; charset=utf-8"; 并确保sendfile off(避免中文文件名问题)。重载nginx:sudo nginx -s reload。
Apache:在httpd.conf或站点配置中加入:AddDefaultCharset UTF-8;或在.htaccess中使用 AddDefaultCharset UTF-8。重启Apache服务。
4. PHP/Java/Node等应用层字符集配置
PHP:确保在连接数据库时使用PDO或mysqli设置charset参数,例如 PDO: new PDO("mysql:host=...;dbname=...;charset=utf8mb4", $user, $pass, [PDO::ATTR_ERRMODE=>PDO::ERRMODE_EXCEPTION]); 或执行 $pdo->exec('SET NAMES utf8mb4');
Java:JDBC连接字符串加参数 ?useUnicode=true&characterEncoding=UTF-8;并可加 -Dfile.encoding=UTF-8 JVM 参数。
Node.js:mysql模块连接时指定 charset: 'utf8mb4';在express输出头部 res.set('Content-Type','text/html; charset=utf-8')。
5. MySQL / MariaDB 服务器级配置(永久生效)
编辑my.cnf(通常在 /etc/mysql/my.cnf 或 /etc/my.cnf)在 [mysqld] 下加入:character-set-server = utf8mb4 collation-server = utf8mb4_unicode_ci;在 [client] 和 [mysql] 下加入 default-character-set = utf8mb4。重启mysql:sudo systemctl restart mysql。
验证:mysql -e "SHOW VARIABLES WHERE Variable_name LIKE 'character\_set\_%' OR Variable_name LIKE 'collation%';"
6. 数据库/表/字段字符集迁移步骤(生产环境谨慎)
先备份:mysqldump --default-character-set=utf8mb4 -u root -p --routines --triggers --events --databases dbname > db_backup.sql。
转换数据库:ALTER DATABASE dbname CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
转换表:ALTER TABLE tbl_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
若单列需改变:ALTER TABLE tbl_name MODIFY col_name VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
注意:若遇到索引长度超限(utf8mb4较占空间),需将索引长度减小或升级为Barracuda + innodb_large_prefix(MySQL旧版本)或使用 utf8mb4_general_ci 并调整字段长度。
7. 连接层与导入导出注意(避免双重或缺失转码)
- 导出:mysqldump --default-character-set=utf8mb4 ...;导入:mysql --default-character-set=utf8mb4 -u root -p dbname < dump.sql。
- phpMyAdmin:config.inc.php 中 $cfg['DefaultCharset']='utf-8'; 并在导入时选择正确字符集。
- JDBC/PDO/ODBC均需明确charset参数,避免服务器与客户端默认不一致造成双重编码或问号替换。
8. 验证乱码与排查命令
- Web页面:curl -I http://your.domain | grep -i content-type 检查响应头charset;curl http://... | iconv -f utf-8 -t utf-8 >/dev/null 检查是否有效。
- 数据库:SELECT HEX(col) FROM tbl WHERE id=... 检查字节序列;SHOW CREATE TABLE tbl_name 检查列的CHARSET。
- 日志检查:查看nginx/php/mysql日志,寻找 “�” 或 "?" 替换痕迹并追踪是哪一环出现问题。
9. 针对韩国服务器的特殊提示
- 系统默认可能是ko_KR编码,确保同时启用 en_US.UTF-8 或 ko_KR.UTF-8。应用通常更推荐使用 en_US.UTF-8 以减少地域差异造成的问题。
- 若用户主要为中文用户,优先保证整个链路UTF-8统一,避免应用端使用本地编码(如EUC-KR)导致中文乱码。
10. 备份与回滚策略
- 在进行字符集转换前强制全量备份并在测试库恢复后验证中文显示与索引功能。
- 若表巨大,先在测试库按表分批转换再替换生产连接或用线上-线下切换策略(蓝绿部署)。
11. 问:为什么部署在韩国的服务器会遇到中文乱码?
答:通常因为系统locale、Web服务器响应头、应用连接参数或数据库字符集不一致造成。韩国服务器可能默认使用ko_KR或非UTF-8 locale,或MySQL默认不是utf8mb4,客户端未指定连接字符集,导致字节被错误解释或截断,从而出现乱码。
12. 问:最常见的快速检查步骤是什么?
答:快速检查顺序:1) 用locale命令确认操作系统为UTF-8;2) curl -I 检查Content-Type header是否含charset=utf-8;3) mysql SHOW VARIABLES LIKE 'character_set_%';4) 在应用连接字符串添加charset=utf8mb4并重测;5) 若仍问题,备份并在测试库执行表/列的CONVERT TO CHARACTER SET utf8mb4。
13. 问:推荐使用哪个字符集与排序规则?
答:推荐使用 utf8mb4(以支持全部Unicode字符)和 utf8mb4_unicode_ci(或MySQL8的utf8mb4_0900_ai_ci)作为默认collation。对韩文、中文、日文混合场景,utf8mb4_unicode_ci 在排序和比较上更准确;注意索引长度与字段类型的配合,必要时调整索引或使用前缀索引。
来源:韩国服务器搭配中文时的编码处理与数据库字符集注意