You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Delphi XE + Indy 10中TIdHTTP调用WebService的特殊撇号编码问题

解决Delphi XE + Indy 10调用WebService时的特殊字符编码问题

我之前踩过类似的Indy编码坑,你的问题核心是字符集不匹配导致参数被双重编码——你预期发送的是Bev%E2%80%99s(U+2019弯撇号的正确UTF-8 URL编码),但WebService收到的Bev%C3%A2%C2%80%C2%99s,本质是Indy先把Unicode字符用错误的字符集转成了字节,再做了URL编码,相当于把UTF-8字节又当成Latin1字符重新编码了一遍。

解决步骤:

  • 先明确:hoForceEncodeParams确实会强制Indy对URL参数进行编码,但Indy默认使用的字符集不是UTF-8(通常是ASCII或系统默认编码),这才是问题根源。你需要手动指定UTF-8作为请求的字符集,让Indy用正确的编码处理参数。

  • 修改你的代码,添加字符集配置:

    idHttp.ConnectTimeOut := iTimeOut;
    idhttp.HTTPOptions := [hoForceEncodeParams];
    // 关键:指定请求的字符集为UTF-8,确保参数编码时使用UTF-8
    idHTTP.Request.CharSet := 'utf-8';
    // 如果是POST请求,还要给Content-Type加上字符集声明
    idHTTP.Request.ContentType := 'application/x-www-form-urlencoded; charset=utf-8';
    
  • 额外注意:不要手动提前对参数做URL编码!如果你自己先把Bev’s转成Bev%E2%80%99s再传给Indy,hoForceEncodeParams会把%也编码成%25,导致三重编码,反而让问题更糟。

  • 备选方案(手动编码参数):
    如果你更倾向于自己控制编码过程,可以关闭hoForceEncodeParams,用TIdURI.ParamsEncode指定UTF-8编码来处理参数,再拼接URL:

    var
      LParam, LURL: string;
    begin
      LParam := 'Bev’s';
      // 用UTF-8编码对参数做URL编码
      LParam := TIdURI.ParamsEncode(LParam, IndyTextEncoding_UTF8);
      LURL := 'http://your-webservice-endpoint?yourParam=' + LParam;
      
      idHttp.ConnectTimeOut := iTimeOut;
      idhttp.HTTPOptions := []; // 关闭自动编码,避免重复处理
      idHTTP.Request.CharSet := 'utf-8';
      idHTTP.Get(LURL);
    end;
    

验证方法:

可以用Indy自带的TIdLogDebug组件或者第三方抓包工具查看实际发送的请求,确认参数是Bev%E2%80%99s,而不是被重复编码的版本。

内容的提问来源于stack exchange,提问作者M Schenkel

火山引擎 最新活动