标准的URL编码函数?

49

是否有 Delphi 等价于此 .net 方法:

Url.UrlEncode()

注意
我已经好几年没用过 Delphi 了。当我阅读答案时,我注意到有几个备注和替代当前标记的答案。我没有机会测试它们,因此我基于最受欢迎的答案回答。
为了你自己的利益,请稍后查看其他答案,并在决定后投票支持最佳答案,以便每个人都能从你的经验中受益。

13个回答

2
据我所知,您需要自己创建。以下是一个示例。
其中的html标签已保留。

1

TIdUri或HTTPEncode在处理Unicode字符集时存在问题。下面的函数将为您执行正确的编码。

function EncodeURIComponent(const ASrc: string): UTF8String;
const
  HexMap: UTF8String = '0123456789ABCDEF';

  function IsSafeChar(ch: Integer): Boolean;
  begin
    if (ch >= 48) and (ch <= 57) then Result := True    // 0-9
    else if (ch >= 65) and (ch <= 90) then Result := True  // A-Z
    else if (ch >= 97) and (ch <= 122) then Result := True  // a-z
    else if (ch = 33) then Result := True // !
    else if (ch >= 39) and (ch <= 42) then Result := True // '()*
    else if (ch >= 45) and (ch <= 46) then Result := True // -.
    else if (ch = 95) then Result := True // _
    else if (ch = 126) then Result := True // ~
    else Result := False;
  end;
var
  I, J: Integer;
  ASrcUTF8: UTF8String;
begin
  Result := '';    {Do not Localize}

  ASrcUTF8 := UTF8Encode(ASrc);
  // UTF8Encode call not strictly necessary but
  // prevents implicit conversion warning

  I := 1; J := 1;
  SetLength(Result, Length(ASrcUTF8) * 3); // space to %xx encode every byte
  while I <= Length(ASrcUTF8) do
  begin
    if IsSafeChar(Ord(ASrcUTF8[I])) then
    begin
      Result[J] := ASrcUTF8[I];
      Inc(J);
    end
    else if ASrcUTF8[I] = ' ' then
    begin
      Result[J] := '+';
      Inc(J);
    end
    else
    begin
      Result[J] := '%';
      Result[J+1] := HexMap[(Ord(ASrcUTF8[I]) shr 4) + 1];
      Result[J+2] := HexMap[(Ord(ASrcUTF8[I]) and 15) + 1];
      Inc(J,3);
    end;
    Inc(I);
  end;

  SetLength(Result, J-1);
end;

1
我认为这是这段代码的正确来源: https://marc.durdin.net/2012/07/indy-tiduri-pathencode-urlencode-and-paramsencode-and-more/还有一个在移动平台上也可以使用的更新版本: https://marc.durdin.net/2015/08/an-update-for-encodeuricomponent/ - jep
1
在这段代码中(就像它来自的网站上一样),应该注意到空格被错误地编码为“+”。这不是encodeURIComponent应该工作的方式。它应该将其编码为%20:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent 但在移动友好版本中已经修复了。 - jep

0
我想指出的是,如果你更注重正确性而不是效率,最简单的方法就是对每个字符进行十六进制编码,即使这并不严格要求。
今天我需要为一个基本的HTML登录表单提交编码几个参数。在经历了所有选项后,每个选项都有自己的注意事项,我决定编写这个朴素版本,它可以完美地工作:
function URLEncode(const AStr: string): string;
var
  LBytes: TBytes;
  LIndex: Integer;
begin
  Result := '';
  LBytes := TEncoding.UTF8.GetBytes(AStr);
  for LIndex := Low(LBytes) to High(LBytes) do
    Result := Result + '%' + IntToHex(LBytes[LIndex], 2);
end;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接