使用FPC fpjson时字符串中Emoji表情乱码的解决求助
解决fpjson发送Emoji表情乱码问题
问题根源
fpjson的StringToJSONString函数(TJSONString.AsJSON底层依赖该函数)默认会将非ASCII字符转义为Unicode转义序列,同时原代码未明确指定HTTP响应的UTF-8编码,导致客户端解析时出现乱码;直接返回字符串时HTTP服务器自动处理了编码逻辑,而JSON包装后的转义流程会导致反斜杠被二次转义,客户端无法识别。
解决方案
1. 明确设置HTTP响应的UTF-8编码
修改响应的ContentType,添加charset=utf-8,强制客户端以UTF-8编码解析内容:
AResponse.ContentType := 'application/json; charset=utf-8';
2. 让fpjson直接输出UTF-8字符而非转义序列
调用StringToJSONString时指定UseUTF8=True参数,该参数会跳过非ASCII字符的转义,直接输出UTF-8编码的原始字符:
AResponse.Contents.Text := StringToJSONString(wave, True);
如果要保留TJSONString的使用,也可以用该函数替代AsJSON属性来生成内容。
3. 修复代码中的空指针问题
原代码中Handler变量仅声明未创建,运行时会触发访问违规,需补充对象创建逻辑:
Handler := THandler.Create; try // 服务器初始化代码 finally Handler.Free; end;
完整修复后的代码示例
program Demo; {$mode objfpc}{$H+} uses fphttpserver, httpdefs, fpjson, jsonstrings; const wave = '👋'; type THandler = class procedure HandleRequest(Sender: TObject; var ARequest: TFPHTTPConnectionRequest; var AResponse: TFPHTTPConnectionResponse); end; procedure THandler.HandleRequest(Sender: TObject; var ARequest: TFPHTTPConnectionRequest; var AResponse: TFPHTTPConnectionResponse); begin AResponse.ContentType := 'application/json; charset=utf-8'; // 直接生成包含Emoji的JSON字符串 AResponse.Contents.Text := Format('{"emoji":%s}', [StringToJSONString(wave, True)]); end; var httpServer: TFPHttpServer; Handler: THandler; begin Handler := THandler.Create; try httpServer := TFPHttpServer.Create(nil); httpServer.Port := 3000; httpServer.OnRequest := @Handler.HandleRequest; httpServer.Active := true; Writeln('Server running on port 3000, press Enter to exit'); Readln; finally Handler.Free; httpServer.Free; end; end.
额外说明
- 如果需要兼容老旧客户端,必须使用Unicode转义序列,需确保转义后的字符串只被处理一次,避免反斜杠被二次转义。可直接构造包含正确转义的字符串,或检查fpjson版本是否存在重复转义的bug。
- 建议升级到最新稳定版FPC,旧版本的fpjson可能存在UTF-8处理的遗留问题。
内容的提问来源于stack exchange,提问作者geisterfurz007
相关产品推荐
相关产品推荐

