此代碼啓動一個HTTP服務器,該服務器偵聽端口8080上的請求。使用Delphi 2009編譯時,中文文本呈現正確。但是,使用Free Pascal 2.6.0時,瀏覽器將顯示ä¸æ–‡
而不是中文
。TIdHTTPServer與Free Pascal的UTF-8響應
使用Indy和Free Pascal編寫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.Write不同的代碼被執行,爲的Free Pascal,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;
是什麼'ASrcEncoding'上.WRITE的進入? Delphi 2009+對於字符串和FPC 2.6通常使用UTF-16(但並不總是AFAIK)使用UTF-8 – 2013-04-11 13:38:57
@ Arioch'ASrcEncoding爲零,這意味着Write將使用encOSDefault(即我的Windows系統上的Ansi)。你確定'string'是Free Pascal 2.6.0上的Unicode嗎?我查過的一些頁面表明它仍然是Ansi。所以我猜這個代碼不能通過使用ContentText屬性來工作,我需要一個字節流。 – mjn 2013-04-11 13:48:37
因爲我知道它在2.4或2.6左右發生了變化 - 並且!它取決於編譯器選項。至少在默認情況下,我的Win7 x64使用最近的CodeTyphon構建它是UTF-8(但是對於基於象形文字的語言,它可能會不同)。 (並且談到編碼 - 沒有像Unicode這樣的字眼)。那麼,我認爲即使在目標Delphi和FPC上,Indy也得不到支持,我甚至不會嘗試使用它......嘗試在FPC上將FDefAnsiEncoding設置爲UTF-8。而且afair正確的是RFC的小寫「utf-8」。 – 2013-04-11 13:51:42