delphi XE10.4 idhttp post Json中文乱码的处理

    一、问题提出
    近期,由于与另一PHP程序之间,动态传递JSON数据,使用delphi XE10.4中idhttp控件实施。代码完成,出现三个问题:
    1、JSON文本定长自动加入“=”;
    2、英文和数字显示正常,中文显示为“????”;
    3、Post反馈的信息中,如有汉字不能显示。

    二、问题探索
    1、通过生成UTF8格式文件,再导入上传,显示的汉字不是“????”,而是乱码了。 

    StringStream := TStringStream.Create('', TEncoding.UTF8);
    StringStream.WriteString(Json1.ToString);
    StringStream.SaveToFile(FileName);

    2、通过实践,将Josnk 汉字转成UTF8格式,如:“中文汉字”,可以显示“中文汉字”。说明Post过程中,中文没有以UTF8格式传递。
    (1)首先在JSON字符生成时,改成UTF8,也不行。
    (2)HTTPEncode(Ansitoutf8(S)),Utf8Encode(s),HttpEncode(UTF8Encode(S)),UTF8Decode(HttpDecode(S2),偿试均失败。
    (3)AddFormField('data', '中文汉字', 'utf-8');  已指定utf-8格式,还是不行;
    3、换个思路,Delphi发展到XE10,在汉字轮换上不可以需要我们如此大费功夫,应该能很好地实现的,是否格式上有问题。同时,定长自动加入“=”问题,肯定在传递的格式(网络传输的字节流)有问题,经查TIdFormDataField有个ContentTransfer属性。

    IdMultipartFormData.pas单元文件中,ContentTransfer有三种类型:

const
  sContentTransferPlaceHolder = 'Content-Transfer-Encoding: %s';     
  sContentTransferQuotedPrintable = 'quoted-printable';              
  sContentTransferBinary = 'binary';                                 

    Delphi默认ContentTransfer第二种:sContentTransferQuotedPrintable,就是'引用可打印'; 它是7位可打印的 ASCII编码方式。每个高位为1的码翻译为如=A1的16进制模式。

    这种模式下,每76个字符用quoted-printable插入一次。这就是出现多余的=\\r\\n(“软”换行符)的原因。在支持quoted-printable服务器,都将在解码期间删除“软”换行符。

    由于对方服务器不支持quoted-printable,所以解码后,加入了“=”等字符。

    原因找到,那就换个模式吧。

    换Binary类型试试:   

  paramStream.AddFormField('data',jsonstr,'UTF-8').ContentTransfer := sContentTransferBinary;

    Post问题都解决。

    4、分析:
    (1)由于ContentTransfer默认sContentTransferQuotedPrintable,Post的'quoted-printable'格式,出现“=”字符。
    (2)设置ContentTransfer为sContentTransferBinary后,它是数据流传输格式,实现UTF-8完整传输。(这里值得斟酌:它不编码的10进制数据流)

    三、问题解决
 

procedure TMainFrm.Button5Click(Sender: TObject);
var paramStream: TIdMultiPartFormDataStream;
    vResponse: TStringStream;
    jsonstr: string;
    MyList:TStringList;
begin
  paramStream := TIdMultiPartFormDataStream.Create;
  vResponse := TStringStream.Create('');
  MyList:=TStringList.Create;
  jsonstr:=GetJosnTxt;                                  // 生成Json的自定义函数 
// 定义http消息头
  idhttp1.Request.ContentType := 'application/json';
//传递普通参数
  paramStream.AddFormField('data',jsonstr,'UTF-8').ContentTransfer := sContentTransferBinary;  // Binary格式传输       
// 执行Post
  IdHTTP1.Post('http://XXX.XXXX.com/api/v1/data', paramStream, vResponse); // 隐藏XXX 
  vres := vResponse.DataString;                         // Post返回值Utf8码
  Memo1.Text := UnicodeToChinese(vres);                 // 显示反馈信息Utf8To
  s:=FormatdateTime('yyyy-MM-dd HH:SS:mm',Now)+#13#10;
  sTemp:=sTemp+S+Memo1.Text;
  MyList:=TStringList.Create;
  MyList.Text:=sTemp;
  MyList.SaveToFile(sMainPath+'Upload.log');            // 保存Post信息 
  paramStream.Free;
  vResponse.Free;
end;

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Delphi 2010 是一个集成开发环境(IDE),供开发者使用 Object Pascal 编程语言。要使用 Delphi 2010 的 IdHTTP 组件进行 JSON 提交,首先需要将 IdHTTP 组件放置在窗体的设计区域或者手动创建一个 IdHTTP 对象。 在代码中,需要导入 IdHTTP 单元,然后创建一个 IdHTTP 对象。然后,使用 Post 方法将 JSON 数据提交到服务器。在 Post 方法中,我们需要设置请求的 URL,并将 JSON 数据转换为字节数组。 具体代码如下: 1. 首先,确保你已经导入 IdHTTP 单元: ``` uses IdHTTP; ``` 2. 在窗体或类的声明部分,添加一个私有变量来持有 IdHTTP 对象: ``` private Http: TIdHTTP; ``` 3. 在创建窗体或类的构造函数中,创建 IdHTTP 对象并设置一些属性: ``` constructor TForm1.Create(AOwner: TComponent); begin inherited Create(AOwner); Http := TIdHTTP.Create(Self); Http.HandleRedirects := True; end; ``` 4. 在需要提交 JSON 数据的地方,使用以下代码: ``` procedure TForm1.PostJSONData(const URL: string; const JSONData: string); var Request: TStringStream; Response: string; begin Request := TStringStream.Create(JSONData, TEncoding.UTF8); try Response := Http.Post(URL, Request); ShowMessage(Response); // 可以根据需要处理服务器的响应结果 finally Request.Free; end; end; ``` 在这个例子中,URL 是目标服务器的地址,JSONData 是要提交的 JSON 数据。完成后,你可以根据需要处理服务器的响应结果。 这是使用 Delphi 2010 的 IdHTTP 组件提交 JSON 数据的简单示例。希望对你有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值