Indy HTTP Server URL 编码请求

问题描述 投票:0回答:1

当 Indy

TIdHTTPServer
收到具有类似于
/find?location=%D1%82%D0%B5%D1%81%D1%82
(UTF-8 url 编码值)这样的 URL 的请求时,
location
中的
RequestInfo.Params
字段具有不可读的值
теÑÑ‚

如何获得可读的值?

我正在使用 Indy 10.6.0.4975。

http encoding indy
1个回答
3
投票

TIdHTTPServer
当前使用
Content-Type
请求标头中指定的字符集解析输入参数,如果没有指定字符集,则使用 Indy 的 8 位编码。这是
TIdHTTPServer
的已知限制,因为目前没有选项告诉它使用用户定义的字符集解码参数。因此,您必须手动解析
ARequestInfo.QueryParams
和/或
ARequestInfo.UnparsedParams
属性,例如通过在其
TIdURI.URLDecode()
参数中使用 UTF-8 编码直接调用
AByteEncoding
,例如:

procedure MyDecodeAndSetParams(ARequestInfo: TIdHTTPRequestInfo);
var
  i, j : Integer;
  value: s: string;
  LEncoding: IIdTextEncoding;
begin
  if IsHeaderMediaType(ARequestInfo.ContentType, 'application/x-www-form-urlencoded') then
  begin
    value := ARequestInfo.FormParams;
    if ARequestInfo.CharSet <> '' then
      LEncoding := CharsetToEncoding(ARequestInfo.CharSet)
    else
      LEncoding := IndyTextEncoding_UTF8;
  end else
  begin
    value := ARequestInfo.QueryParams;
    LEncoding := IndyTextEncoding_UTF8;
  end;

  ARequestInfo.Params.BeginUpdate;
  try
    ARequestInfo.Params.Clear;
    i := 1;
    while i <= Length(value) do
    begin
      j := i;
      while (j <= Length(value)) and (value[j] <> '&') do
      begin
        Inc(j);
      end;
      s := StringReplace(Copy(value, i, j-i), '+', ' ', [rfReplaceAll]);
      ARequestInfo.Params.Add(TIdURI.URLDecode(s, LEncoding));
      i := j + 1;
    end;
  finally
    ARequestInfo.Params.EndUpdate;
  end;
end;

procedure TForm1.IdHTTPServer1CommandGet(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
begin
  MyDecodeAndSetParams(ARequestInfo);
  ...
end;

更新:自 2021 年 2 月起,如果

TIdHTTPServer
标头中未指定字符集,
Content-Type
现在默认使用 UTF-8 解析输入参数。因此不再需要上述解决方法。

更新:如果您仍然需要在旧版本中使用上述解决方法,我已将代码更新为现在默认为UTF-8(如果解析时

ARequestInfo.CharSet
为空)。
    

© www.soinside.com 2019 - 2024. All rights reserved.