在 GET 请求中使用 URL 中的希腊字母
Use Greek letters in URL in GET request
我正在 Delphi 10.4 中开发一个 Android 应用程序。我的客户端通过网络服务与服务器通信。
我使用带有 GET 方法的按名称搜索服务来获取名称列表,具体取决于我输入的字母是英语还是希腊语 TEdit
。代码行如下所示:
mydata := IdHTTP1.GET('http://.../Names/search/'+Edit1.Text);
每次用户在 TEdit
和 returns 中输入以用户输入的文本的第一个字母开头的字母时,都会调用该请求。
当我使用英文字母时,搜索工作正常,但当我使用希腊字母时,它无法正常工作。相反,它 returns 所有名称列表 1.
我在浏览器中使用希腊字母尝试路径,如下所示:http://.../Names/search/Αντ
,它起作用了,returns 以 Αντ
开头的名称。但是在应用程序中,它不起作用。
会不会是TEdit
或TIdHTTP
组件的编码有误?
好像不读希腊字母,发的是空字符串
1因为如果路径是:http://.../Names/search/
,它returns所有的名字列表。
我的代码如下所示:
procedure TForm1.Edit1ChangeTracking(Sender: TObject);
var
mydata : string;
jsv,js : TJSONValue;
originalObj,jso : TJSONObject;
jsa : TJSONArray;
i: Integer;
begin
Memo1.Lines.Clear;
try
IdHTTP1.Request.ContentType := 'application/json';
IdHTTP1.Request.CharSet := 'utf-8';
IdHTTP1.Request.AcceptLanguage := 'gr';
IdHTTP1.Request.ContentEncoding := 'UTF-8';
mydata := IdHTTP1.Get('http://.../Names/search/'+Edit1.Text);
except
on E: Exception do
begin
ShowMessage(E.Message);
end;
end;
try
jsv := TJSONObject.ParseJSONValue(TEncoding.UTF8.GetBytes(mydata),0) as TJSONValue;
try
jsa := jsv as TJSONArray;
for i := 0 to jsa.Size-1 do
begin
jso := jsa.Get(I) as TJSONObject;
js := jso.Get('Name').JsonValue;
Memo1.Lines.Add(js.Value);
if i=4 then // show the 5 first names of the search
break;
end;
finally
jsv.Free();
end;
except
on E: exception do
begin
ShowMessage(E.Message);
end;
end;
end;
URLs 不能包含 未编码 non-ASCII 字符。您不能只附加 TEdit
文本 as-is,您需要 url-encode 任何 non-ASCII 字符,以及 URI 规范保留的字符。
如果您使用浏览器的 built-in 调试器,您会发现它在向服务器传输请求时实际上是在进行这种编码。例如,URL 像:http://.../Names/search/Αντ
发送这样的请求:
GET /Names/search/%CE%91%CE%BD%CF%84 HTTP/1.1
Host: ...
...
通知Αντ
=>%CE%91%CE%BD%CF%84
在您的代码中,您可以使用 Indy 的 TIdURI
class 来实现此目的,例如:
uses
..., IdURI;
mydata := IdHTTP1.GET('http://.../Names/search/'+TIdURI.PathEncode(Edit1.Text));
旁注:
由于您发送的是 GET 请求,因此不需要设置 Request.ContentType
、Request.CharSet
或 Request.ContentEncoding
属性(此外,'UTF-8'
无效ContentEncoding
无论如何)。
此外,ParseJSONValue()
有一个需要 string
的重载,因此您不需要使用 TEncoding.UTF8.GetBytes()
.
我正在 Delphi 10.4 中开发一个 Android 应用程序。我的客户端通过网络服务与服务器通信。
我使用带有 GET 方法的按名称搜索服务来获取名称列表,具体取决于我输入的字母是英语还是希腊语 TEdit
。代码行如下所示:
mydata := IdHTTP1.GET('http://.../Names/search/'+Edit1.Text);
每次用户在 TEdit
和 returns 中输入以用户输入的文本的第一个字母开头的字母时,都会调用该请求。
当我使用英文字母时,搜索工作正常,但当我使用希腊字母时,它无法正常工作。相反,它 returns 所有名称列表 1.
我在浏览器中使用希腊字母尝试路径,如下所示:http://.../Names/search/Αντ
,它起作用了,returns 以 Αντ
开头的名称。但是在应用程序中,它不起作用。
会不会是TEdit
或TIdHTTP
组件的编码有误?
好像不读希腊字母,发的是空字符串
1因为如果路径是:http://.../Names/search/
,它returns所有的名字列表。
我的代码如下所示:
procedure TForm1.Edit1ChangeTracking(Sender: TObject);
var
mydata : string;
jsv,js : TJSONValue;
originalObj,jso : TJSONObject;
jsa : TJSONArray;
i: Integer;
begin
Memo1.Lines.Clear;
try
IdHTTP1.Request.ContentType := 'application/json';
IdHTTP1.Request.CharSet := 'utf-8';
IdHTTP1.Request.AcceptLanguage := 'gr';
IdHTTP1.Request.ContentEncoding := 'UTF-8';
mydata := IdHTTP1.Get('http://.../Names/search/'+Edit1.Text);
except
on E: Exception do
begin
ShowMessage(E.Message);
end;
end;
try
jsv := TJSONObject.ParseJSONValue(TEncoding.UTF8.GetBytes(mydata),0) as TJSONValue;
try
jsa := jsv as TJSONArray;
for i := 0 to jsa.Size-1 do
begin
jso := jsa.Get(I) as TJSONObject;
js := jso.Get('Name').JsonValue;
Memo1.Lines.Add(js.Value);
if i=4 then // show the 5 first names of the search
break;
end;
finally
jsv.Free();
end;
except
on E: exception do
begin
ShowMessage(E.Message);
end;
end;
end;
URLs 不能包含 未编码 non-ASCII 字符。您不能只附加 TEdit
文本 as-is,您需要 url-encode 任何 non-ASCII 字符,以及 URI 规范保留的字符。
如果您使用浏览器的 built-in 调试器,您会发现它在向服务器传输请求时实际上是在进行这种编码。例如,URL 像:http://.../Names/search/Αντ
发送这样的请求:
GET /Names/search/%CE%91%CE%BD%CF%84 HTTP/1.1
Host: ...
...
通知Αντ
=>%CE%91%CE%BD%CF%84
在您的代码中,您可以使用 Indy 的 TIdURI
class 来实现此目的,例如:
uses
..., IdURI;
mydata := IdHTTP1.GET('http://.../Names/search/'+TIdURI.PathEncode(Edit1.Text));
旁注:
由于您发送的是 GET 请求,因此不需要设置 Request.ContentType
、Request.CharSet
或 Request.ContentEncoding
属性(此外,'UTF-8'
无效ContentEncoding
无论如何)。
此外,ParseJSONValue()
有一个需要 string
的重载,因此您不需要使用 TEncoding.UTF8.GetBytes()
.