Delphi TIdHTTP.Get() API 当参数值包含 space 时失败并返回 400 Bad Request

Delphi TIdHTTP.Get() API fails with 400 Bad Request when parameter value contains space

我正在使用 TIdHTTP.Get() 方法向 API 发送一些参数。

我从 string 变量或组件 Text 属性(例如 ComboBox)中提取实际 API 参数的值。一切都很好,直到这些值中的任何一个包含 space.

例如其中一个参数是全名字段(例如:'John Smith'

因为它在名字和姓氏之间包含一个 space,一旦我使用 te TIdHTTP.Get() 方法将它发送到 API,它就会抛出一个 400 Bad Request 错误失败了。

如果我从 that/any 特定参数的值中删除 space,它会正常运行。

我用来测试的代码:

httpObject := TIdHTTP.Create;
    
httpObject.HTTPOptions := [hoForceEncodeParams];
httpobject.MaxAuthRetries := 3;
httpObject.ProtocolVersion := pv1_1;
httpObject.Request.Accept := 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8';
httpObject.Request.UserAgent := 'Mozilla/3.0 (compatible;Indy Library)';
httpObject.Request.ContentType := 'application/x-www-form-urlencoded; charset=utf-8';
    
URL := 'url string containing the parameters'; //string variable
httpObject.Get(URL);

API 文档说:

我该如何解决这个问题?

使用 Delphi 社区版(即 10.3)及其随附的 Indy 组件。

您已声明您以 Content-Type: application/x-www-form-urlencoded

的身份提交数据

该格式不允许有空格。您需要对提交的内容进行正确编码。

您可以通过两种方式做到这一点:

印地:

Encoded := TIdURI.URLEncode(str);

使用 TNetEncoding

Encoded := TNetEncoding.URL.Encode(str);

您在 URL 中发送参数,而不是在请求正文中,因此设置 Request.ContentType 属性 和启用 hoForceEncodeParams 选项是完全没有必要的,可以被省略。

您需要编码参数值,当您建立URL发送请求。您可以为此使用 TIdURI class,例如:

uses
  ..., IdHTTP, IdURI;

URL := 'http://server/shipment?param1='+TIdURI.ParamsEncode(value1)+'&param2='+TIdURI.ParamsEncode(value2)...;
httpObject.Get(URL);