2009-04-22 78 views
40

是否有德尔福相当于该.NET的方法:标准的URL编码功能?

Url.UrlEncode()

注意
我还没有与德尔福现在工作了好几年。 当我通读答案时,我注意到当前标记的答案有几种备注和备选方案。我没有机会测试它们,所以我将我的答案作为最高优先级。
为了您自己的利益,请检查后面的答案,并在决定upvote最佳答案后,让每个人都可以从您的经验中受益。

回答

91

看在印第安纳波利斯IdURI单元,它在TIdURI类两个静态方法用于编码/解码的URL。

uses 
    IdURI; 

.. 
begin 
    S := TIdURI.URLEncode(str); 
// 
    S := TIdURI.URLDecode(str); 
end; 
+6

boris,来吧,接受这个答案,我只是给了它一个点,完全有帮助:) – 2009-04-23 13:59:11

+0

不错,我不知道这一点。很有帮助。 – 2011-03-01 09:00:33

+3

@彼得赫,我没有检查这个问题,因为我不再使用Delphi。但是,无论如何你仍然在这里;) – 2011-09-07 13:15:02

3

AFAIK你需要自己做。

这里是一个例子。

+1

对不起,但这是不正确的,请检查其他答案。 – 2009-04-23 12:02:23

+1

我站好了。 – 2009-04-23 17:03:57

13

另一种选择,就是在SynaCode单元使用Synapse库,其具有一个简单的URL编码方法(以及许多其他)。

uses 
    SynaCode; 
.. 
begin 
    s := EncodeUrl(str); 
// 
    s := DecodeUrl(str); 
end; 
13
class function TIdURI.ParamsEncode(const ASrc: string): string; 
var 
    i: Integer; 
const 
    UnsafeChars = '*#%<> []'; {do not localize} 
begin 
    Result := ''; {Do not Localize} 
    for i := 1 to Length(ASrc) do 
    begin 
    if CharIsInSet(ASrc, i, UnsafeChars) or (not CharIsInSet(ASrc, i, CharRange(#33,#128))) then begin {do not localize} 
     Result := Result + '%' + IntToHex(Ord(ASrc[i]), 2); {do not localize} 
    end else begin 
     Result := Result + ASrc[i]; 
    end; 
    end; 
end; 

从印。


反正印不能正常工作,所以你需要看到这篇文章
http://marc.durdin.net/2012/07/indy-tiduripathencode-urlencode-and.html

12

我自己做了这个功能进行编码,除了真正的安全角色的一切。特别是我有问题+。请注意,您无法使用此功能对整个网址进行编码,但您需要对您想要没有特别含义的部分进行编码,通常是变量的值。

function MyEncodeUrl(source:string):string; 
var i:integer; 
begin 
    result := ''; 
    for i := 1 to length(source) do 
     if not (source[i] in ['A'..'Z','a'..'z','0','1'..'9','-','_','~','.']) then result := result + '%'+inttohex(ord(source[i]),2) else result := result + source[i]; 
end; 
16

这样做的另一种简单的方法是使用HTTPEncode功能在HTTPApp单元 - 非常粗略

Uses 
    HTTPApp; 

function URLEncode(const s : string) : string; 
begin 
    result := HTTPEncode(s); 
end 
2

我也面临着同样的问题(德尔福4)。

function fnstUrlEncodeUTF8(stInput : widestring) : string; 
    const 
    hex : array[0..255] of string = (
    '%00', '%01', '%02', '%03', '%04', '%05', '%06', '%07', 
    '%08', '%09', '%0a', '%0b', '%0c', '%0d', '%0e', '%0f', 
    '%10', '%11', '%12', '%13', '%14', '%15', '%16', '%17', 
    '%18', '%19', '%1a', '%1b', '%1c', '%1d', '%1e', '%1f', 
    '%20', '%21', '%22', '%23', '%24', '%25', '%26', '%27', 
    '%28', '%29', '%2a', '%2b', '%2c', '%2d', '%2e', '%2f', 
    '%30', '%31', '%32', '%33', '%34', '%35', '%36', '%37', 
    '%38', '%39', '%3a', '%3b', '%3c', '%3d', '%3e', '%3f', 
    '%40', '%41', '%42', '%43', '%44', '%45', '%46', '%47', 
    '%48', '%49', '%4a', '%4b', '%4c', '%4d', '%4e', '%4f', 
    '%50', '%51', '%52', '%53', '%54', '%55', '%56', '%57', 
    '%58', '%59', '%5a', '%5b', '%5c', '%5d', '%5e', '%5f', 
    '%60', '%61', '%62', '%63', '%64', '%65', '%66', '%67', 
    '%68', '%69', '%6a', '%6b', '%6c', '%6d', '%6e', '%6f', 
    '%70', '%71', '%72', '%73', '%74', '%75', '%76', '%77', 
    '%78', '%79', '%7a', '%7b', '%7c', '%7d', '%7e', '%7f', 
    '%80', '%81', '%82', '%83', '%84', '%85', '%86', '%87', 
    '%88', '%89', '%8a', '%8b', '%8c', '%8d', '%8e', '%8f', 
    '%90', '%91', '%92', '%93', '%94', '%95', '%96', '%97', 
    '%98', '%99', '%9a', '%9b', '%9c', '%9d', '%9e', '%9f', 
    '%a0', '%a1', '%a2', '%a3', '%a4', '%a5', '%a6', '%a7', 
    '%a8', '%a9', '%aa', '%ab', '%ac', '%ad', '%ae', '%af', 
    '%b0', '%b1', '%b2', '%b3', '%b4', '%b5', '%b6', '%b7', 
    '%b8', '%b9', '%ba', '%bb', '%bc', '%bd', '%be', '%bf', 
    '%c0', '%c1', '%c2', '%c3', '%c4', '%c5', '%c6', '%c7', 
    '%c8', '%c9', '%ca', '%cb', '%cc', '%cd', '%ce', '%cf', 
    '%d0', '%d1', '%d2', '%d3', '%d4', '%d5', '%d6', '%d7', 
    '%d8', '%d9', '%da', '%db', '%dc', '%dd', '%de', '%df', 
    '%e0', '%e1', '%e2', '%e3', '%e4', '%e5', '%e6', '%e7', 
    '%e8', '%e9', '%ea', '%eb', '%ec', '%ed', '%ee', '%ef', 
    '%f0', '%f1', '%f2', '%f3', '%f4', '%f5', '%f6', '%f7', 
    '%f8', '%f9', '%fa', '%fb', '%fc', '%fd', '%fe', '%ff'); 
var 
    iLen,iIndex : integer; 
    stEncoded : string; 
    ch : widechar; 
begin 
    iLen := Length(stInput); 
    stEncoded := ''; 
    for iIndex := 1 to iLen do 
    begin 
    ch := stInput[iIndex]; 
    if (ch >= 'A') and (ch <= 'Z') then 
     stEncoded := stEncoded + ch 
    else if (ch >= 'a') and (ch <= 'z') then 
     stEncoded := stEncoded + ch 
    else if (ch >= '0') and (ch <= '9') then 
     stEncoded := stEncoded + ch 
    else if (ch = ' ') then 
     stEncoded := stEncoded + '+' 
    else if ((ch = '-') or (ch = '_') or (ch = '.') or (ch = '!') or (ch = '*') 
     or (ch = '~') or (ch = '\') or (ch = '(') or (ch = ')')) then 
     stEncoded := stEncoded + ch 
    else if (Ord(ch) <= $07F) then 
     stEncoded := stEncoded + hex[Ord(ch)] 
    else if (Ord(ch) <= $7FF) then 
    begin 
     stEncoded := stEncoded + hex[$c0 or (Ord(ch) shr 6)]; 
     stEncoded := stEncoded + hex[$80 or (Ord(ch) and $3F)]; 
    end 
    else 
    begin 
     stEncoded := stEncoded + hex[$e0 or (Ord(ch) shr 12)]; 
     stEncoded := stEncoded + hex[$80 or ((Ord(ch) shr 6) and ($3F))]; 
     stEncoded := stEncoded + hex[$80 or ((Ord(ch)) and ($3F))]; 
    end; 
    end; 
    result := (stEncoded); 
end; 

来源:Java source code

5

在最近版本的Delphi(与XE5测试)的,使用在REST.Utils单位URIEncode功能

我使用下述功能解决了这个问题。

3

我已经作出了自己的功能。它将空格转换为%20,而不是加号。需要将本地文件路径转换为浏览器路径(使用file:///前缀)。最重要的是它处理UTF-8字符串。它的灵感来自Radek Hladik的解决方案。

function URLEncode(s: string): string; 
var 
    i: integer; 
    source: PAnsiChar; 
begin 
    result := ''; 
    source := pansichar(s); 
    for i := 1 to length(source) do 
    if not (source[i - 1] in ['A'..'Z', 'a'..'z', '0'..'9', '-', '_', '~', '.', ':', '/']) then 
     result := result + '%' + inttohex(ord(source[i - 1]), 2) 
    else 
     result := result + source[i - 1]; 
end;  
0

TIdUri或HTTPEncode在unicode字符集中存在问题。下面的函数会为你做正确的编码。

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

    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;