2009-04-22 7 views
40

Y at-il un équivalent Delphi de la méthode de cette .net:Fonction d'encodage d'URL standard?

Url.UrlEncode()

Remarque
Je n'ai pas travaillé avec Delphi depuis plusieurs années. En lisant les réponses, je remarque qu'il y a plusieurs remarques et alternatives à la réponse marquée. Je n'ai pas eu l'occasion de les tester alors je base ma réponse sur les plus upvoted.
Dans votre propre intérêt, vérifiez les réponses ultérieures et, après avoir décidé d'afficher la meilleure réponse, afin que tout le monde puisse bénéficier de votre expérience.

Répondre

91

Regardez l'unité indy IdURI, il dispose de deux méthodes statiques dans la classe TIdURI pour/Encode l'URL en décodage.

uses 
    IdURI; 

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

boris, allez, acceptez cette réponse, je viens de lui donner un point pour être totalement utile :) –

+0

Nice, je ne savais pas cela. Très utile. –

+3

@Peter Heh, je n'ai pas vérifié cette question car je ne travaille plus avec Delphi. Mais ici vous allez quand même;) –

3

AFAIK vous devez faire votre propre.

Voici un exemple.

+1

Désolé, mais ce n'est pas correct, vérifiez les autres réponses. –

+1

Je suis corrigé. –

13

Une autre option est d'utiliser la bibliothèque Synapse qui a une méthode simple de codage URL (ainsi que beaucoup d'autres) dans l'unité SynaCode.

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

Dans un environnement non-dotnet, l'unité Wininet permet d'accéder à la fonction encode WinHTTP 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.


Quoi qu'il en soit Indy ne fonctionne pas correctement si VOUS BESOIN POUR VOIR CETTE ARTICLE:
http://marc.durdin.net/2012/07/indy-tiduripathencode-urlencode-and.html

+8

Autel et Marc Durdin ont raison. TIdURI est cassé. Unit REST.Utils fournit une fonction, Uriencode, qui fonctionne correctement. –

12

Je me suis fait cette fonction pour encoder des caractères tout sauf vraiment en sécurité. Surtout j'ai eu des problèmes avec +. Sachez que vous ne pouvez pas encoder l'URL entière avec cette fonction, mais vous devez enregistrer les parties que vous ne voulez pas avoir de signification particulière, généralement les valeurs des 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

Ceci devrait être la réponse acceptée. (pas sûr comment il gère UTF-8 si) –

+0

Il a un problème avec les chartes Unicode. par exemple. % 633% 6CC% 628 est le résultat de la chaîne unicode 'سیب' il sera décodé en 'c3lCb8' – Mahoor13

+0

Grande réponse. Sûrement, ceci et toutes les solutions codées faites sur commande sur cette page devraient seulement encoder des caractères dangereux, plutôt qu'excluant des caractères sûrs. Seul l'espace et les caractères ayant une signification particulière dans les URI doivent être codés. Par exemple. [Emb DokWiki] (http://docwiki.embarcadero.com/Libraries/Tokyo/en/System.NetEncoding.TURLEncoding) indique que "TURLEncoding encode uniquement les espaces (comme les signes plus: +) et les caractères d'encodage d'URL réservés suivants:; & = +, /?% # []. " – DaveBoltman

16

Une autre façon simple de le faire est d'utiliser la fonction HTTPEncode dans l'unité HTTPApp - très grossièrement

Uses 
    HTTPApp; 

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

je également face à la même question (Delphi 4).

Je résolu le problème en utilisant la fonction ci-dessous mentionnée:

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; 

source: Java source code

5

Dans les versions récentes de Delphi (testé avec XE5), utilisez la fonction URIEncode dans l'unité REST.Utils.

3

J'ai fait ma propre fonction. Il convertit les espaces en% 20, pas en signe plus. Il était nécessaire de convertir le chemin du fichier local en chemin pour le navigateur (avec le préfixe file: ///). Le plus important est qu'il gère les chaînes UTF-8. Il a été inspiré par la solution de Radek Hladik ci-dessus.

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, il a été testé dans Lazarus, mais devrait également fonctionner dans Delphi 2010+. –

0

TIdUri ou HTTPEncode a des problèmes avec charactersets unicode. Fonction ci-dessous fera l'encodage correct pour vous.

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;