IdHTTPServer一些心得
在bcb2007时,比bcb6增加了一个网络控件indy,感觉还比较方便,于是用IdHTTPServer做了个小HTTPServer,感觉挺好的。但随着2008、2010出来,默认的AnsiString变为了UnicodeString,也许是与世界接轨,问题也随着这个大变革出现,我的好工程也无法跟上编译器的脚步,很多三方软件也一样,变的问题多多。
最近无聊想把HTTPServer使用2010下重做,做了一部分,发现中文乱码问题严重。
问题一:
在浏览器的地址栏目中加上中文,如:http://127.0.0.1/你好 而在IdHTTPServer在解码中 ARequestInfo->Document中就出现乱码。通过调试,发现其他地方都没问题,
查看IdCustomHTTPServer.hpp文件,找Document(内部变量FDocument)
if LInputLine = '*' then begin {Do not Localize}
LRequestInfo.FDocument := '*'; {Do not Localize}
end else begin
LURI := TIdURI.Create(LInputLine);
try
// SG 29/11/01: Per request of Doychin
// Try to fill the "host" parameter
LRequestInfo.FDocument := TIdURI.URLDecode(LURI.Path) + TIdURI.URLDecode(LURI.Document);
//LRequestInfo.FDocument :=LURI.Path+LURI.Document;
if (Length(LURI.Host) > 0) and (Length(LRequestInfo.FHost) = 0) then begin
LRequestInfo.FHost := LURI.Host;
end;
finally
FreeAndNil(LURI);
end;
end;
在此解码的主要是靠TIdURI.URLDecode()函数
通过另外小实验,发现URLDecode()函数的问题,由于不会修改,就此放弃
接着又安装了xe2,发现这个问题在xe里解决了,可以正常显示中文,呵呵
小结:地址栏里放中文的问题在xe2下正常了
问题2:向浏览器发送页面数据(含汉字),网页默认为西文,需要在浏览器手动设置编码为中文
为什么bcb2007下正常,而2010和xe下总不是默认为中文
代码:
AResponseInfo->ContentText="你好!1111111111111111112222";
或者(返回流)
String str="你好!111111111111111111111111";
TMemoryStream *mms=new TMemoryStream;
mms->Write(str.c_str(),str.Length());
mms->Position=0;
AResponseInfo->FreeContentStream=false;
AResponseInfo->ContentStream=mms;
通过抓包发现问题:
//bcb2007
HTTP/1.1 200 OK
Connection: close
Content-Type: text/html
Content-Length: 29
Server: Indy/10.1.5
//bcb XE
HTTP/1.1 200 OK
Connection: close
Content-Type: text/html; charset=ISO-8859-1
Content-Length: 27
找到问题,charset=ISO-8859-1
立即实验:
在上面代码前加上
AResponseInfo->CharSet="gb2312";//哈哈,问题解决
(注意:设置为空也不行)
综上实验,如果大家要利用idhttpserver做一个服务器,选择bcb2007是个不错的选择,问题比较少,如果想与时俱进,那选择最新版本,内部编码改变带来的问题,会在新版本中慢慢更正
随便加一句,xe里的firemonkey真的很漂亮,就是控件不如原来的多,呵呵
[解决办法]
是的新版本总会有bug只能等补丁,或自己改。
[解决办法]
不错的心得,字符编码这一关总是要过的