serialize()中文乱码

本文介绍了一个关于使用jQuery的.serialize()方法自动调用encodeURIComponent进行数据编码的问题,并提供了解决方案,即通过调用decodeURIComponent方法来解码数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1 原因:.serialize()自动调用了encodeURIComponent方法将数据编码了    
2 解决方法:调用decodeURIComponent(XXX,true);将数据解码    
3 例如:    
4 var params = jQuery("#formId").serialize(); // http request parameters.    
5 params = decodeURIComponent(params,true);  
如果在使用 RapidJSON 处理 GBK 编码的中文时出现乱码,是因为 RapidJSON 默认使用 UTF-8 编码,而 GBK 与 UTF-8 不兼容。以下是解决方案: ### 解决方案(支持 GBK 编码) #### 1. 修改序列化/反序列化方法(添加 GBK 转换) ```cpp #include "AppConfig.h" #include <fstream> #include <iostream> #include <locale> #include <codecvt> #include "rapidjson/error/en.h" // GBK 与 UTF-8 转换工具函数 std::string GbkToUtf8(const std::string& gbkStr) { std::wstring_convert<std::codecvt_byname<wchar_t, char, std::mbstate_t>> conv(new std::codecvt_byname<wchar_t, char, std::mbstate_t>("zh_CN.gbk")); std::wstring wstr = conv.from_bytes(gbkStr); std::wstring_convert<std::codecvt_utf8<wchar_t>> utf8_conv; return utf8_conv.to_bytes(wstr); } std::string Utf8ToGbk(const std::string& utf8Str) { std::wstring_convert<std::codecvt_utf8<wchar_t>> utf8_conv; std::wstring wstr = utf8_conv.from_bytes(utf8Str); std::wstring_convert<std::codecvt_byname<wchar_t, char, std::mbstate_t>> conv(new std::codecvt_byname<wchar_t, char, std::mbstate_t>("zh_CN.gbk")); return conv.to_bytes(wstr); } rapidjson::Document AppConfig::Serialize() const { rapidjson::Document doc; doc.SetObject(); auto& allocator = doc.GetAllocator(); // 封装添加成员的宏(自动处理GBK->UTF-8转换) #define ADD_MEMBER_GBK(name) \ doc.AddMember(rapidjson::Value(#name, allocator).Move(), \ rapidjson::Value().SetString(GbkToUtf8(name).c_str(), allocator), allocator) ADD_MEMBER_GBK(PluginPath); ADD_MEMBER_GBK(Version); // ...其他字段(同上) ADD_MEMBER_GBK(PermeateToolName); // 会自动转换GBK到UTF-8 // ...其他字段 #undef ADD_MEMBER_GBK return doc; } void AppConfig::Deserialize(const rapidjson::Document& doc) { #define GET_STRING_GBK(name) \ if (doc.HasMember(#name) && doc[#name].IsString()) { \ name = Utf8ToGbk(doc[#name].GetString()); \ } GET_STRING_GBK(PluginPath); GET_STRING_GBK(Version); // ...其他字段(同上) GET_STRING_GBK(PermeateToolName); // 会自动转换UTF-8到GBK // ...其他字段 #undef GET_STRING_GBK } ``` #### 2. 修改文件读写方法(直接处理 GBK) ```cpp bool AppConfig::SaveToFile(const std::string& filename) const { rapidjson::Document doc = Serialize(); // 写入文件(使用文本模式) std::ofstream ofs(filename); if (!ofs.is_open()) { std::cerr << "无法打开文件: " << filename << std::endl; return false; } // 使用普通Writer(因为内部已经转为UTF-8) rapidjson::OStreamWrapper osw(ofs); rapidjson::PrettyWriter<rapidjson::OStreamWrapper> writer(osw); writer.SetIndent(' ', 2); doc.Accept(writer); return true; } bool AppConfig::LoadFromFile(const std::string& filename) { std::ifstream ifs(filename); if (!ifs.is_open()) { std::cerr << "无法打开文件: " << filename << std::endl; return false; } // 读取GBK编码的文件内容 std::string content((std::istreambuf_iterator<char>(ifs)), std::istreambuf_iterator<char>()); // 将GBK内容转为UTF-8后再解析 std::string utf8Content = GbkToUtf8(content); rapidjson::Document doc; doc.Parse(utf8Content.c_str()); if (doc.HasParseError()) { std::cerr << "JSON解析错误: " << rapidjson::GetParseError_En(doc.GetParseError()) << std::endl; return false; } Deserialize(doc); return true; } ``` ### 替代方案(推荐) 如果系统支持,更推荐使用 **UTF-8 with BOM** 格式,这样编辑器能自动识别编码: ```cpp bool AppConfig::SaveToFile(const std::string& filename) const { rapidjson::Document doc = Serialize(); // 写入UTF-8 BOM头 std::ofstream ofs(filename, std::ios::binary); if (!ofs.is_open()) return false; // UTF-8 BOM (EF BB BF) ofs << "\xEF\xBB\xBF"; rapidjson::OStreamWrapper osw(ofs); rapidjson::PrettyWriter<rapidjson::OStreamWrapper> writer(osw); writer.SetIndent(' ', 2); doc.Accept(writer); return true; } ``` ### 关键问题说明 1. **乱码原因**: - RapidJSON 内部使用 UTF-8,而你的源数据是 GBK - 直接序列化会导致 GBK 被当作 UTF-8 处理 2. **解决方案对比**: - **方案1**:在序列化时将 GBK → UTF-8,反序列化时 UTF-8 → GBK - **方案2**:统一使用 UTF-8 存储(推荐),通过 BOM 标记文件编码 3. **Windows 平台注意事项**: - 如果必须使用 GBK,确保文件打开时使用文本模式(`std::ios::binary` 会禁用编码转换) - 现代 Windows 系统(Win10+)对 UTF-8 支持更好,建议迁移到 UTF-8 ### 最佳实践建议 1. **优先使用 UTF-8**: ```cpp // 在程序启动时设置全局locale(Windows专用) #ifdef _WIN32 std::setlocale(LC_ALL, ".65001"); // UTF-8 codepage #endif ``` 2. **如果必须保留 GBK**: - 确保整个数据处理流程(文件读写、字符串处理)统一使用 GBK - 避免 UTF-8 和 GBK 混用 3. **调试技巧**: - 用十六进制编辑器检查文件实际编码 - 在关键位置打印字符串的十六进制值: ```cpp void printHex(const std::string& s) { for (unsigned char c : s) { printf("%02X ", c); } printf("\n"); } ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值