web-dev-qa-db-fra.com

Fonction de codage d'URL standard?

Existe-t-il un équivalent de Delphi de la méthode de ce réseau:

Url.UrlEncode ()

Remarque
Je n'ai pas travaillé avec Delphi depuis plusieurs années maintenant . En lisant les réponses, je constate qu'il existe plusieurs remarques et alternatives à la réponse actuellement marquée. Je n'ai pas eu l'occasion de les tester, donc je me base sur les plus votés.
Pour votre propre intérêt, vérifiez les réponses ultérieures et après avoir décidé de choisir la meilleure réponse afin que tout le monde puisse bénéficier de votre expérience.

42
Boris Callens

Regardez l’unité IdyRI indy, elle a deux méthodes statiques dans la classe TIdURI pour Encoder/Décoder l’URL.

uses
  IdURI;

..
begin
  S := TIdURI.URLEncode(str);
//
  S := TIdURI.URLDecode(str);
end;
93
Mohammed Nasman

Une autre méthode simple consiste à utiliser la fonction HTTPEncode dans l’unité HTTPApp - très approximativement.

Uses 
  HTTPApp;

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

Je me suis fait cette fonction pour tout encoder sauf les caractères vraiment sûrs. Surtout j'ai eu des problèmes avec +. Sachez que vous ne pouvez pas encoder l'intégralité de l'URL avec cette fonction, mais que vous avez besoin d'encoder les parties pour lesquelles 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;
13
Radek Hladík

Mise à jour 2018: le code ci-dessous semble être obsolète. voir le commentaire de Remy.

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;

D'Indy.


Quoi qu’il en soit, Indy ne fonctionne pas correctement, donc VOUS DEVEZ VOIR CET ARTICLE:
http://marc.durdin.net/2012/07/indy-tiduri-pathencode-urlencode-and-paramsencode-and-more/

13
Rigel

Une autre option consiste à utiliser la bibliothèque Synapse qui possède une méthode de codage d’URL simple (ainsi que de nombreuses autres) dans l’unité SynaCode

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

Depuis Delphi xe7, vous pouvez utiliser TNetEncoding.Url.Encode ()

9
Enny

Dans un environnement autre que Dotnet, l’unité Wininet fournit un accès à la fonction de codage WinHTTP de Windows: InternetCanonicalizeUrl

6
Stijn Sanders

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

5
James Roscoe

Je faisais également face au même problème (Delphi 4). 

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

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: code source Java

5
Abhineet

Autant que je sache, vous devez créer le vôtre.

Voici un exemple.

3
Ólafur Waage

J'ai créé ma propre fonction. Il convertit les espaces en% 20 et non en signe plus. Il était nécessaire de convertir le chemin de fichier local en chemin de navigateur (avec le préfixe fichier: ///) 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;       
3
GAD ZombiE

TIdUri ou HTTPEncode a des problèmes avec les jeux de caractères unicode. La fonction ci-dessous fera un encodage correct pour vous.

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
Alpay Abay

J'aimerais souligner que si vous vous souciez beaucoup plus de la correction que de l'efficacité, le plus simple que vous puissiez faire est de coder tous les caractères au format hexadécimal, même si cela n'est pas strictement nécessaire. 

Aujourd’hui, j’avais besoin de coder quelques paramètres pour la soumission d’un formulaire de connexion HTML de base. Après avoir passé en revue toutes les options, chacune avec leurs propres mises en garde, j'ai décidé d'écrire cette version naïve qui fonctionne parfaitement:

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;
0
Thijs van Dien