【问题标题】:Encoding Apostrophe for Indy Call为 Indy Call 编码撇号
【发布时间】:2018-01-31 14:40:51
【问题描述】:

我正在使用 Delphi XE 和 Indy 10。我正在使用 TIdHTTP 调用 Web 服务,其中参数包含非标准撇号:Bev’sBev's

以 urlencoded 形式,我将参数传递为:Bev%E2%80%99s

但是网络服务将其解释为:Bev%C3%A2%C2%80%C2%99s

相关代码:

idHttp.ConnectTimeOut := iTimeOut;
idhttp.HTTPOptions := [hoForceEncodeParams];

有什么地方我必须指定它以某种方式编码吗?

【问题讨论】:

  • 让 Indy 对该参数进行编码。

标签: delphi indy


【解决方案1】:

%C3%A2%C2%80%C2%99 是字节 E2 80 99 的 UTF-8 编码形式的 urlencoded 形式,它又是 字符的 UTF-8 编码形式。因此,您遇到了双重编码问题, 在被 urlencoded 之前被编码为 UTF-8 两次。

hoForceEncodeParams 标志由TIdHTTPSetRequestParams() 方法使用,该方法由具有ASource: TStrings 输入参数的Post() 方法的重载版本调用。

function Post(AURL: string; ASource: TStrings; AByteEncoding: IIdTextEncoding = nil): string; overload;
procedure Post(AURL: string; ASource: TStrings; AResponseContent: TStream; AByteEncoding: IIdTextEncoding = nil); overload;

如果启用了hoForceEncodeParams 标志,则字符串应在输入时未编码SetRequestParams() 会将它们字符集编码为字节(基于指定的AByteEncoding 参数,其中默认为 UTF-8),然后对字节进行 url 编码,例如:

idhttp.HTTPOptions := idhttp.HTTPOptions + [hoForceEncodeParams];
data := TStringList.Create;
data.Add('name=Bev’s');
idhttp.Post(url, data); // sends 'name=Bev%E2%80%99s'
data.Free;

如果hoForceEncodeParams 标志被禁用,则字符串应在输入时进行url 编码SetRequestParams() 不会对他们做任何事情,他们是按原样发送的,例如:

idhttp.HTTPOptions := idhttp.HTTPOptions - [hoForceEncodeParams];
data := TStringList.Create;
data.Add('name=Bev%E2%80%99s');
idhttp.Post(url, data); // sends 'name=Bev%E2%80%99s'
data.Free;

【讨论】:

  • 感谢您提供非常详细的评论。但是我正在做一个“获取”而不是一个帖子。在 Get 上,我看到未调用 SetRequestParams 方法。
  • @MSchenkel 不,不是,因为GET 请求不会发送正文。 GET 发送的唯一参数在 URL 本身中,跟在未编码的 ? 字符之后,例如:http://host/path?params。在这种情况下,您需要将预编码的 URL 传递给TIdHTTP,然后它按原样将其发送到服务器。如果您将Bev%E2%80%99s 传递给TIdHTTP,这就是它发送的方式,而不是Bev%C3%A2%C2%80%C2%99sTIdHTTP 不会对 URL 进行解码和重新编码。不过,您没有提供 minimal reproducible example 来准确显示您是如何使用 TIdHTTP 的。
猜你喜欢
  • 2011-08-30
  • 1970-01-01
  • 2012-05-24
  • 2017-09-25
  • 1970-01-01
  • 2013-01-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多