Recent

Author Topic: Problem with IdHTTP1Get(RequestURL_Final);  (Read 2366 times)

manhu

  • New Member
  • *
  • Posts: 27
Problem with IdHTTP1Get(RequestURL_Final);
« on: April 19, 2018, 11:06:08 am »
Hi

I have a Problem with a request from a website ( google ). The Problem is when the URL ( Edit_str.Text ) contains umlaute ( öäü ), without it works fine.

Code: Pascal  [Select][+][-]
  1. procedure Tfrm_maps.geocoding(Sender: TObject);
  2. var
  3.    RequestURL, RequestURL_Final:string;
  4.    jData : TJSONData;
  5. begin
  6.  
  7.      if Edit_str.Text <> '' then
  8.      begin
  9.        with IdHTTP1 do
  10.          try
  11.             RequestURL  := 'https://maps.googleapis.com/maps/api/geocode/json?address='+Edit_str.Text+',+'+Edit_city.Text+'+'+Edit_plz.text+'&key='+var_g_api_key+'';
  12.             RequestURL_final := StringReplace(RequestURL, ' ', '+', [rfReplaceAll]);
  13.             json  := Get(RequestURL_Final);
  14.          finally
  15.            jData := GetJSON(json);
  16.            if AnsiContainsText(json, '"status" : "ZERO_RESULTS"') then
  17.            begin
  18.                 ShowMessage('Error happened: ZERO_RESULTS');
  19.            end
  20.            else
  21.            begin
  22.                 var_gps_lat :=  FloatToStrF(jData.FindPath('results[0].geometry.location.lat').AsFloat,ffGeneral,20,15);
  23.                 var_gps_lng :=  FloatToStrF(jData.FindPath('results[0].geometry.location.lng').AsFloat,ffGeneral,20,15);
  24.            end;
  25.          end;
  26.      end;
  27. end;  
  28.  

The answer i get whne the Failure  IdHTTP1.get ocours is:
Quote
'{'#10'   "results" : [],'#10'   "status" : "ZERO_RESULTS"'#10'}'#10

If anybody has a tip... ;)

Shalom
Manfred

rvk

  • Hero Member
  • *****
  • Posts: 6163
Re: Problem with IdHTTP1Get(RequestURL_Final);
« Reply #1 on: April 19, 2018, 11:15:27 am »
You need to URLEncode Edit_str.Text etc. before adding it to the URL.

Not sure if there is a ready made URLEncode in Lazarus/FPC but you could try this:

Code: Pascal  [Select][+][-]
  1. {
  2.   URLEncode
  3.   Encodes string to be suitable as an URL. (ie. replaces for example a space with %20)
  4.   Example:      myencodeURL:=URLEncode(myURL);
  5. }
  6. function URLEncode(s: string): string;
  7. var
  8.   i: integer;
  9.   source: PAnsiChar;
  10. begin
  11.   result := '';
  12.   source := pansichar(s);
  13.   for i := 1 to length(source) do
  14.     if not (source[i - 1] in ['A'..'Z', 'a'..'z', '0'..'9', '-', '_', '~', '.', ':', '/']) then
  15.       result := result + '%' + inttohex(ord(source[i - 1]), 2)
  16.     else
  17.       result := result + source[i - 1];
  18. end;
« Last Edit: April 19, 2018, 11:17:15 am by rvk »

manhu

  • New Member
  • *
  • Posts: 27
Re: Problem with IdHTTP1Get(RequestURL_Final);
« Reply #2 on: April 19, 2018, 11:33:37 am »
Thank you very much.
Great  ::)

Code: Pascal  [Select][+][-]
  1. procedure Tfrm_maps.geocoding(Sender: TObject);
  2. var
  3.    RequestURL, RequestURL_Final:string;
  4.    jData : TJSONData;
  5. begin
  6.      if Edit_str.Text <> '' then
  7.      begin
  8.        with IdHTTP1 do
  9.          try
  10.             RequestURL  := 'https://maps.googleapis.com/maps/api/geocode/json?address='+URLEncode(Edit_str.Text)+',+'+URLEncode(Edit_city.Text)+'+'+Edit_plz.text+'&key='+var_g_api_key+'';
  11.             RequestURL_Final := StringReplace(RequestURL, ' ', '+', [rfReplaceAll]);
  12.             json  := Get(RequestURL_Final);
  13.          finally
  14.            jData := GetJSON(json);
  15.            if AnsiContainsText(json, '"status" : "ZERO_RESULTS"') then
  16.            begin
  17.                 ShowMessage('Error happened: ZERO_RESULTS');
  18.            end
  19.            else
  20.            begin
  21.                 var_gps_lat :=  FloatToStrF(jData.FindPath('results[0].geometry.location.lat').AsFloat,ffGeneral,20,15);
  22.                 var_gps_lng :=  FloatToStrF(jData.FindPath('results[0].geometry.location.lng').AsFloat,ffGeneral,20,15);
  23.            end;
  24.          end;
  25.      end;
  26. end;  

Zath

  • Sr. Member
  • ****
  • Posts: 391
Re: Problem with IdHTTP1Get(RequestURL_Final);
« Reply #3 on: April 19, 2018, 11:33:43 am »
They are classed as unsafe characters.
The safe characters are a-z, A-Z, 0-9, underscore and hyphen.

I don't know if any component can achieve this off the shelf.

This might be of interest.
https://cachefly.zendesk.com/hc/en-us/articles/215068626-How-to-format-URLs-that-have-special-characters-in-the-filename-

manhu

  • New Member
  • *
  • Posts: 27
Re: Problem with IdHTTP1Get(RequestURL_Final);
« Reply #4 on: April 19, 2018, 11:43:07 am »
@Zath; Thank you also for your Answer.
I did also try to convert the Edit_str.Text before i pass it to the URL.

But this did not work for me. Could not get this to work with this code:
( The code just did not replace anything...)

Code: Pascal  [Select][+][-]
  1. function replace_umlaut(s: String): String;
  2. var
  3.   i: integer;
  4. begin
  5.     Result := '';
  6.     for i := 1 to Length(s) do
  7.     begin
  8.       case s[i] of
  9.         #196: Result := Result + 'Ae'; // Ä
  10.         #214: Result := Result + 'Oe'; // Ö
  11.         #220: Result := Result + 'Ue'; // Ü
  12.         #228: Result := Result + 'ae'; // ä
  13.         #246: Result := Result + 'oe'; // ö
  14.         #252: Result := Result + 'ue'; // ü
  15.         #223: Result := Result + 'ss'; // ß
  16.       else
  17.         Result := Result + s[i];
  18.       end;
  19.     end;
  20. end;      

Remy Lebeau

  • Hero Member
  • *****
  • Posts: 1314
    • Lebeau Software
Re: Problem with IdHTTP1Get(RequestURL_Final);
« Reply #5 on: April 20, 2018, 09:05:25 pm »
You need to URLEncode Edit_str.Text etc. before adding it to the URL.

Not sure if there is a ready made URLEncode in Lazarus/FPC

TIdHTTP is an Indy component.  Indy also has a TIdURI class for dealing with URL encodings.

Also, TIdHTTP.Get() raises an exception if the HTTP request fails.  The original code did not take that into account, so the json string would be empty if Get() failed, causing GetJSON() to also fail and raise its own exception.

Also, FindPath() returns nil if the requested value is not found. The original code did not take that into account, either.  Use GetPath() instead, and let it raise its own exception if the requested value is not found.

Try this instead:

Code: Pascal  [Select][+][-]
  1. procedure Tfrm_maps.geocoding(Sender: TObject);
  2. var
  3.   RequestURL: string;
  4.   jData, jLocation : TJSONData;
  5.   json, status: string;
  6. begin
  7.   if Edit_str.GetTextLen = 0 then Exit;
  8.   RequestURL  := 'https://maps.googleapis.com/maps/api/geocode/json?address=' + TIdURI.ParamsEncode(Edit_str.Text) + ',+' + TIdURI.ParamsEncode(Edit_city.Text) + '+' + TIdURI.ParamsEncode(Edit_plz.Text) + '&key=' + TIdURI.ParamsEncode(var_g_api_key);
  9.   // or:
  10.   // RequestURL  := 'https://maps.googleapis.com/maps/api/geocode/json?address=' + TIdURI.ParamsEncode(Edit_str.Text + ', ' + Edit_city.Text + ' ' + Edit_plz.Text) + '&key=' + TIdURI.ParamsEncode(var_g_api_key);
  11.   try
  12.     json  := IdHTTP1.Get(RequestURL);
  13.     jData := GetJSON(json);
  14.     status := jData.GetPath('status').AsString;
  15.     if status <> 'OK' then
  16.     begin
  17.       ShowMessage('Google Error happened: ' + status);
  18.     end
  19.     else
  20.     begin
  21.       jLocation := jData.GetPath('results[0].geometry.location');
  22.       var_gps_lat := FloatToStrF(jLocation.GetPath('lat').AsFloat, ffGeneral, 20, 15);
  23.       var_gps_lng := FloatToStrF(jLocation.GetPath('lng').AsFloat, ffGeneral, 20, 15);
  24.     end;
  25.   except
  26.     on E: EIdHTTPProtocolException do begin
  27.       ShowMessage('HTTP Error happened: ' + E.Message);
  28.     end;
  29.     on E: Exception do begin
  30.       ShowMessage('Unknown Error happened: ' + E.Message);
  31.     end;
  32.   end;
  33. end;
  34.  
« Last Edit: April 23, 2018, 10:58:19 pm by Remy Lebeau »
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

manhu

  • New Member
  • *
  • Posts: 27
Re: Problem with IdHTTP1Get(RequestURL_Final);
« Reply #6 on: April 23, 2018, 02:36:54 pm »
@Remy Lebeau: Thank you very much for the Help  :)

 

TinyPortal © 2005-2018