indy httpserver 接收URL包含中文参数乱码的问题

来源:互联网 发布:mysql数据库建表 编辑:程序博客网 时间:2024/05/18 11:41

在测试TIdHttpServer的时候,发现浏览器提交的URL包含中文时会乱码,我用的是XE7 UPDATE1,INDY是10。

procedure TForm1.idhtpsrv1CommandGet(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo;
  AResponseInfo: TIdHTTPResponseInfo);

在这事件处理中文时,AResponseInfo好办,只要设置下

  AResponseInfo.ContentType := 'text/html';
  AResponseInfo.CharSet := 'utf-8';

浏览器就能正确显现中文。


对于 ARequestInfo,回头想想一开始决解方向就错了,不要想着各种编码转换,实际到这里,INDY已经把编码转换好了,因为到这里处理的文本,

 ARequestInfo.Params.Text已经是string类型了(UNICODE)。网上说是改INDY的源码,因为没地方设置TIdHTTPRequestInfo编码属性。

改动的是IdCustomHTTPServer.pas的 TIdHTTPRequestInfo.DecodeAndSetParams(const AValue: String)方法:


procedure TIdHTTPRequestInfo.DecodeAndSetParams(const AValue: String);var  i, j : Integer;  s: string;  LEncoding: IIdTextEncoding;begin  // Convert special characters  // ampersand '&' separates values    {Do not Localize}  Params.BeginUpdate;  try    Params.Clear;    CharSet := 'utf-8';  //添加这一行                                                                  // which charset to use for decoding query string parameters.  We    // should not be using the 'Content-Type' charset for that.  For    // 'application/x-www-form-urlencoded' forms, we should be, though...    LEncoding := CharsetToEncoding(CharSet);    i := 1;    while i <= Length(AValue) do    begin      j := i;      while (j <= Length(AValue)) and (AValue[j] <> '&') do {do not localize}      begin        Inc(j);      end;      s := Copy(AValue, i, j-i);      // See RFC 1866 section 8.2.1. TP      s := StringReplace(s, '+', ' ', [rfReplaceAll]);  {do not localize}      Params.Add(TIdURI.URLDecode(s, LEncoding));      i := j + 1;    end;  finally    Params.EndUpdate;  end;end;

然后重新编译IndyProtocols包,注意bpl文件放在bin下,dcu和dcp文件放在Lib下的各个相应目录下(就是win32/win64, debug/release)

测试代码:


procedure TForm1.idhtpsrv1CommandGet(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo;  AResponseInfo: TIdHTTPResponseInfo);begin  AResponseInfo.ContentType := 'text/html';  AResponseInfo.CharSet := 'utf-8';  mmo1.Lines.Add('=====================');  mmo1.Lines.Add('Document:');  mmo1.Lines.Add('');  mmo1.Lines.Add(ARequestInfo.Params.Text);  mmo1.Lines.Add('p1: '+ ARequestInfo.Params.Values['p1']);  mmo1.Lines.Add('p2: '+ ARequestInfo.Params.Values['p2']);  AResponseInfo.ContentText := '是中文吧'; // 'HttpServer OK';end;

浏览器URL:http://127.0.0.1:8000/test?p1=中文&p2=ghg

用 Chrome,edge,360浏览器测试正确。


0 0