UTF-8 response of TIdHTTPServer with Free Pascal

原链接:原链接


问题 (Question)

This code starts a HTTP server which listens for requests on port 8080. When compiled with Delphi 2009, the Chinese text is rendered correctly. With Free Pascal 2.6.0 however, the browser displays ä¸­æ–‡ instead of 中文.

What is the correct way to write Unicode / UTF-8 HTTP responses with Indy and Free Pascal?

这段代码启动HTTP服务器在端口8080上侦听请求。在Delphi 2009中编译时,中文文本正确呈现。然而,与自由帕斯卡2.6.0浏览器显示中文而不是中文 .

正确的方法是什么写Unicode utf - 8 / HTTP响应与印第安纳·琼斯和帕斯卡有空吗?

program IdHTTPUnicode;

{$APPTYPE CONSOLE}

uses
  IdHTTPServer, IdCustomHTTPServer, IdContext, IdSocketHandle, IdGlobal,
  SysUtils;

type
  TMyServer = class (TIdHTTPServer)
  public
    procedure InitComponent; override;
    procedure DoCommandGet(AContext: TIdContext;
      ARequestInfo: TIdHTTPRequestInfo;
      AResponseInfo: TIdHTTPResponseInfo); override;
  end;

procedure Demo;
var
  Server: TMyServer;
begin
  Server := TMyServer.Create(nil);
  try
    try
      Server.Active := True;
    except
      on E: Exception do
      begin
        WriteLn(E.ClassName + ' ' + E.Message);
      end;
    end;
    WriteLn('Hit any key to terminate.');
    ReadLn;
  finally
    Server.Free;
  end;
end;

procedure TMyServer.InitComponent;
var
  Binding: TIdSocketHandle;
begin
  inherited;

  Bindings.Clear;
  Binding := Bindings.Add;
  Binding.IP := '127.0.0.1';
  Binding.Port := 8080;
  Binding.IPVersion := Id_IPv4;
end;

procedure TMyServer.DoCommandGet(AContext: TIdContext;
  ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
const
  UNI = '中文';
begin
  AResponseInfo.ContentText := '<html>' + UNI + '</html>';
  AResponseInfo.ContentType := 'text/html';
  AResponseInfo.CharSet := 'UTF-8';
end;

begin
  Demo;
end.


在调试器中,我可以看到,TIdIOHandler不同的代码的方法。免费写执行,帕斯卡,STRING_IS_ANSI定义:


procedure TIdIOHandler.Write(const AOut: string; AByteEncoding: TIdTextEncoding = nil
  {$IFDEF STRING_IS_ANSI}; ASrcEncoding: TIdTextEncoding = nil{$ENDIF}
  );
begin
  if AOut <> '' then begin
    AByteEncoding := iif(AByteEncoding, FDefStringEncoding);
    {$IFDEF STRING_IS_ANSI}
    ASrcEncoding := iif(ASrcEncoding, FDefAnsiEncoding, encOSDefault);
    {$ENDIF}
    Write(
      ToBytes(AOut, -1, 1, AByteEncoding
        {$IFDEF STRING_IS_ANSI}, ASrcEncoding{$ENDIF}
        )
      );
  end;
end; 


FreePascal字符串是utf - 16编码不像他们在Delphi 2009 +。FreePascal,在Delphi 2007和以前的版本中,您的代码需要考虑实际的字符串编码。这就是为什么赛车公开其他Ansi-based参数/属性为这些平台。

当TIdHTTPServer写出ContentText使用TIdIOHandler.Write(),ASrcEncoding参数没有使用unicode平台上,所以你必须使用TIdIOHandler.DefAnsiEncoding财产而不是让Write()知道的编码ContentText如:

procedure TMyServer.DoCommandGet(AContext: TIdContext;
  ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
const
  UNI: WideString = '中文';
begin
  AResponseInfo.ContentText := UTF8Encode('<html>' + UNI + '</html>');
  AResponseInfo.ContentType := 'text/html';

  // this tells TIdHTTPServer what to encode bytes to during socket transmission
  AResponseInfo.CharSet := 'utf-8';

  // this tells TIdHTTPServer what encoding the ContentText is using
  // so it can be decoded to Unicode prior to then being charset-encoded
  // for output. If the input and output encodings are the same, the
  // Ansi string data gets transmitted as-is without decoding/reencoding...
  AContext.Connection.IOHandler.DefAnsiEncoding := IndyUTF8Encoding;
end;




在现代FreePascal默认字符串是utf - 8,除非你调整copil选项。

因此似乎在iif(ASrcEncoding, FDefAnsiEncoding, encOSDefault);的价值encOSDefault是错误的。你可以解决它的检测在印第安纳·琼斯来源如果你喜欢或我想更好的设置DefAnsiEncoding := 'utf-8';(由RFC拖欠的低)

在安全方面你可以检查utf - 8模式在程序开始。设置一些非拉丁常数(如中国的事情,或希腊或斯拉夫字母——不管)和检查如果是UTF8:http://compaspascal.blogspot.ru/2009/03/utf-8-automatic-detection.html

不过总的来说,我认为你可能会发现一些库,关心FPC和Linux比印第安纳·琼斯。印地赛车似乎我停滞不前,甚至遗弃在Delphi旁边。也许Synopse mORMot(寻找DataSnap性能测试文章)可以帮助你或者一些附带的库CodeTyphon发行版。





  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
由于lazarus中的例子: lazarus\fpc\2.6.0\source\packages\fcl-web\examples\webdata\demo 用的extjs是3.4版,在新的extjs4.2环境下不能运行,费了好大劲,终于搞定。期间到laz英文论坛提问,可能跟我英文差有关吧,一个回答的都没有。搞定后,版主又要我进行了“ open a new issue in the bugtracker and add a diff with the changes ”。本着互助、共享的原则,整个东西放到lazarus中文社区论坛,欢迎大家不断改善源码,提高性能,并且将改善后的源码进行共享。 我的环境:winxp,lazarus1.1,fpc2.6.0,apache2.2,extjs4.2。 不要犯怵,安装配置很简单,运行这个demo一行代码都不需要编写。后面我会详细讲安装运行方法。 安装配置: 1、安装Apache。下载地址:http://www.fayea.com/apache-mirror//httpd/binaries/win32/httpd-2.2.22-win32-x86-openssl-0.9.8t.msi 其他版本我没试过,高版本的应该可以。 我安装到了D:\apache2.2 2、下载安装Extjs4.2。下载地址:http://cdn.sencha.io/ext-4.2.0-beta.zip?ref=extjs.org.cn 下载后,解压缩,文件夹复制到 D:\apache2.2\htdocs\,然后改名为Ext。 3、下载附件。 原来的lazarus demo 源码未做任何修改,直接编译即可。编译之前需要安装weblaz和lazwebextra两个包。 本文附件中已经有extgrid.exe,可以直接使用。 将extgrid.exe和users.dbf复制到 apache2.2\cgi-bin 目录下。 将附件中其余文件复制到 apache2.2\htdocs\demodbf 目录下。 好了,全部配置完成。 4、启动Apache,访问:http://localhost/demodbf/extgrid-json.html

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值