2009-04-22 19 views
40

¿Existe un equivalente de Delphi del método de esta .net:Función de codificación de URL estándar?

Url.UrlEncode()

Nota
No he trabajado con Delphi desde hace varios años. Al leer las respuestas, noto que hay varias observaciones y alternativas a la respuesta actualmente marcada. No he tenido la oportunidad de probarlos, así que estoy basando mi respuesta en los más votados.
Por su propio bien, revise las respuestas posteriores y luego de decidir vota la mejor respuesta para que todos puedan beneficiarse de su experiencia.

Respuesta

91

mirada a la unidad IdURI Indy, que cuenta con dos métodos estáticos de la clase TIdURI de codificación/decodificación de la URL.

uses 
    IdURI; 

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

boris, vamos, acepta esta respuesta, solo le di un punto por ser totalmente útil :) –

+0

Bien, no sabía esto. Muy útil. –

+3

@Peter Heh, no revisé esta pregunta ya que no estoy trabajando con Delphi. Pero aquí va de todos modos;) –

3

AFAIK tiene que hacer la suya propia.

Aquí hay un ejemplo.

+1

Lo sentimos, pero esto no es correcto, verifique las otras respuestas. –

+1

Soy corregido. –

13

Otra opción, es utilizar la biblioteca Synapse que tiene un método simple de codificación URL (así como muchos otros) en la unidad de SynaCode.

uses 
    SynaCode; 
.. 
begin 
    s := EncodeUrl(str); 
// 
    s := DecodeUrl(str); 
end; 
6

En un entorno no dotnet, la unidad Wininet proporciona acceso a la función WinHTTP encode de Windows': InternetCanonicalizeUrl

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; 

De Indy.


De todos modos Indy no está funcionando correctamente para necesita ver ESTE ARTÍCULO:
http://marc.durdin.net/2012/07/indy-tiduripathencode-urlencode-and.html

+8

Altar y Marc Durdin tienen razón. TIdurI está roto. La unidad REST.Utils proporciona una función, URIEncode, que funciona correctamente. –

12

me he hecho esta función para codificar todo excepto caracteres muy seguras. Especialmente tuve problemas con +. Tenga en cuenta que no puede codificar toda la URL con esta función, pero debe incluir las partes que desea que no tengan ningún significado especial, generalmente los valores de las 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; 
+0

Esta debería ser la respuesta aceptada. (no estoy seguro de cómo maneja UTF-8) –

+0

Tiene un problema con los charecters unicode. p.ej. % 633% 6CC% 628 es el resultado de la cadena unicode 'سیب' se decodificará a 'c3lCb8' – Mahoor13

+0

Gran respuesta. Seguramente, esta y todas las soluciones codificadas personalizadas en esta página solo deberían codificar caracteres peligrosos, en lugar de excluir caracteres seguros. Solo el espacio y los caracteres que tienen un significado especial en los URI deben codificarse. P.ej. [Emb DokWiki] (http://docwiki.embarcadero.com/Libraries/Tokyo/en/System.NetEncoding.TURLEncoding) dice "TURLEncoding solo codifica espacios (como signos de más: +) y los siguientes caracteres de codificación de URL reservados:;: & = +, /?% # []. " – DaveBoltman

16

Otra forma sencilla de hacerlo es utilizar la función HTTPEncode en la unidad HTTPApp - muy aproximadamente

Uses 
    HTTPApp; 

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

también estaba enfrentando el mismo problema (Delphi 4).

I resuelto el problema mediante el siguiente función mencionada:

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; 

fuente: Java source code

5

En las versiones recientes de Delphi (probado con XE5), utilice la función URIEncode en la unidad REST.Utils.

3

he hecho mi propia función. Convierte espacios a% 20, no a signo más. Fue necesario convertir la ruta del archivo local a la ruta del navegador (con file: /// prefix). Lo más importante es que maneja cadenas UTF-8. Fue inspirado por la solución anterior de 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

Oh, fue probado en Lazarus, pero también debería funcionar en Delphi 2010+. –

0

TIdUri o HTTPEncode tiene problemas con las características unicode. La función a continuación hará la codificación correcta para usted.

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; 
Cuestiones relacionadas