标准的URL编码function?

是否有一个delphi等同于.net的方法:

  Url.UrlEncode() 

注意
delphi已经有好几年了。 当我通读答案时,我注意到当前标记的答案有几个备注和备选scheme。 我没有机会testing他们,所以我把我的答案build立在最有利的方面。
为了您自己的利益,请检查后面的答案,并决定upvote最好的答案,所以每个人都可以从您的经验中受益。

看indy的IdURI单元,它在TIdURI类中有两个静态方法来对URL进行编码/解码。

uses IdURI; .. begin S := TIdURI.URLEncode(str); // S := TIdURI.URLDecode(str); end; 

另一个简单的方法是在HTTPApp单元中使用HTTPEncode函数 – 非常粗略

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

另一个select是使用SynaCode单元中具有简单URL编码方法(以及其他许多)的Synapse库。

 uses SynaCode; .. begin s := EncodeUrl( str ); // s := DecodeUrl( str ); end; 
 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; 

来自Indy。


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

我让自己这个函数编码除了真正安全的字符以外的所有东西 特别是我有问题+。 请注意,您无法使用此function对整个url进行编码,但您需要将您想要没有特别含义的部分(通常是variables的值)进行编码。

 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; 

既然Delphi xe7可以使用TNetEncoding.Url.Encode()

在非dotnet环境下,Wininet单元提供对Windows的WinHTTP编码function的访问: InternetCanonicalizeUrl

在Delphi的最新版本(使用XE5进行testing)中,使用REST.Utils单元中的URIEncode函数。

AFAIK你需要做你自己的。

这是一个例子。

  • HTTPEncode

我已经做了我自己的function。 它将空格转换为%20,而不是加号。 需要将本地文件path转换为浏览器的path(使用file:///前缀)。 最重要的是它处理UTF-8string。 它的灵感来自Radek Hladik的解决scheme。

 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; 

我也面临同样的问题(delphi4)。

我使用下面提到的函数解决了这个问题:

 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源代码

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 // AZ else if (ch >= 97) and (ch <= 122) then Result := True // az 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;