简体   繁体   English

具有编码UTF8的IdHTTPServer和IdHTTP

[英]IdHTTPServer and IdHTTP with Encoding UTF8

I am testing a localhost server using TIdHTTPServer and TIdHTTP . 我正在使用TIdHTTPServerTIdHTTP测试本地主机服务器。 I am having problems with encoding UTF8 data. 我在编码UTF8数据时遇到问题。

client side: 客户端:

procedure TForm1.SpeedButton1Click(Sender: TObject);
var
  res: string;
begin
  res:=IdHTTP1.Get('http://localhost/?msg=đi chơi thôi');
  Memo1.Lines.Add(res);
end;

Server side: 服务器端:

procedure TForm1.OnCommandGet(AContext: TIdContext;
  ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
begin
  Memo1.Lines.Add(ARequestInfo.Params.Values['msg']); // ?i ch?i th?i

  AResponseInfo.CharSet := 'utf-8';
  AResponseInfo.ContentText := 'chào các bạn'; // chào các b?n
end;

I want to send đi chơi thôi and receive chào các bạn . 我想发送đi chơi thôi并接收chào các bạn But the server receives ?i ch?i th?i and the client receives chào các b?n . 但是,服务器收到?i ch?i th?i和客户端接收chào các b?n

Can anyone help me? 谁能帮我?

TIdHTTP transmits the URL exactly as you give it, but http://localhost/?msg=đi chơi thôi is not a valid URL that can be transmitted as-is, as URLs can only contain ASCII characters. TIdHTTP完全按照您TIdHTTP传输URL,但是http://localhost/?msg=đi chơi thôi不是可以原样传输的有效URL,因为URL仅包含ASCII字符。 Unreserved ASCII characters can be used as-is, but reserved and non-ASCII characters MUST be charset-encoded into bytes and then those bytes must be url-encoded in %HH format, eg: 可以按原样使用未保留的ASCII字符,但是必须将保留和非ASCII字符进行字符集编码为字节,然后必须将这些字节以%HH格式进行url编码,例如:

IdHTTP1.Get('http://localhost/?msg=%C4%91i%20ch%C6%A1i%20th%C3%B4i');

You must ensure you pass only valid url-encoded URLs to TIdHTTP . 您必须确保仅将有效的URL编码URL传递给TIdHTTP

In this example, the URL is hard-coded, but if you need something more dynamic then use the TIdURI class, eg: 在此示例中,URL是硬编码的,但是如果您需要更动态的TIdURI ,请使用TIdURI类,例如:

IdHTTP1.Get('http://localhost/?msg=' + TIdURI.ParamsEncode('đi chơi thôi'));

TIdHTTPServer will then decode the parameter data as you are expecting. 然后, TIdHTTPServer将按照您的期望对参数数据进行解码。 Both TIdURI and TIdHTTPServer use UTF-8 by default. 默认情况下, TIdURITIdHTTPServer使用UTF-8。

When sending a response, you are only setting a CharSet , but you are not setting a ContentType . 发送响应时,仅设置CharSet ,而不设置ContentType So TIdHTTPServer will set the ContentType to 'text/html; charset=ISO-8859-1' 因此TIdHTTPServer会将ContentType设置为'text/html; charset=ISO-8859-1' 'text/html; charset=ISO-8859-1' , overwriting your CharSet . 'text/html; charset=ISO-8859-1' ,覆盖您的CharSet You need to explicitly set the ContentType yourself so you can specify a custom CharSet , eg: 您需要自己明确设置ContentType以便可以指定自定义CharSet ,例如:

AResponseInfo.ContentType := 'text/plain';
AResponseInfo.CharSet := 'utf-8';
AResponseInfo.ContentText := 'chào các bạn';

Or: 要么:

AResponseInfo.ContentType := 'text/plain; charset=utf-8';
AResponseInfo.ContentText := 'chào các bạn';

On a side note, TIdHTTPServer is a multi-threaded component. 附带说明一下, TIdHTTPServer是一个多线程组件。 The OnCommand... events are fired in the context of a worker thread, not the main UI thread. OnCommand...事件是在辅助线程而不是主UI线程的上下文中触发的。 So accessing Memo1 directly like you are is not thread-safe. 因此,像您Memo1直接访问Memo1并不是线程安全的。 You MUST synchronize with the main UI thread in order to access UI controls safely, eg: 您必须与主UI线程同步,以便安全地访问UI控件,例如:

procedure TForm1.OnCommandGet(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
var
  msg: string;
begin
  msg := ARequestInfo.Params.Values['msg'];
  TThread.Synchronize(nil,
    procedure
    begin
      Memo1.Lines.Add(msg);
    end
  );
  ...
end;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM