2

我正在使用 Delphi 字符串(Delphi XE)动态生成 HTML。将重音字符编码到我的 HTML 中的正确方法是什么?

var
 s : string;
 myHTML : string;

(...)
s:= 'programação';
 myHTML:= 
'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'+#10+
'<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">'+#10+
(...)
'<title>OmneeK Server - Intraweb</title>'+#10+
'<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />'+#10+
(...)

myHTML:= myHTML + '<font color="red">' + s + '</font>';

(...)

使用上面的代码我得到(从浏览器):

"programa��o"

我试过 HTMLEncode 但结果是一样的。我正在使用 ICS 组件来处理 HTTP 请求。

4

5 回答 5

4

看来您没有以 UTF-8 编码保存页面

试试这个样本

Var
  Page :  TStrings;
begin
  Page:=TStringList.Create;
  try
    Page.Add('<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" lang="en">');
    Page.Add('<meta http-equiv="Content-Type" content="text/html; charset="UTF-8" />');
    Page.Add('<title>Test</title>');
    Page.Add('<p>programação</p>');
    Page.Add('</html>');
    Page.SaveToFile(ChangeFileExt(ParamStr(0),'.html'), TEncoding.UTF8);
  finally
    Page.Free;
  end;
end;
于 2012-06-28T14:39:44.367 回答
2

@米格尔·E

我在 Delphi XE4 / Indy 10 中发现了一些有趣的东西(可能也适用于早期版本)。这可能是您问题的根源吗?

如果您在写入 TIdHTTPResponseInfo.CharSet 之后写入 TIdHTTPResponseInfo.ContentType,那么您将丢失写入 TIdHTTPResponseInfo.CharSet 的内容!

换句话说:(给定信息:TIdHTTPResponseInfo)

  Info.ContentType := 'text/html';   // Warning!  Setting this AFTER setting CharSet changes CharSet back to ISO8859-1.
  Info.CharSet := 'UTF-8';           // So we MUST set CharSet last!

In fact, there is NOTHING else you have to do (other than write to Info.ContentText) in order to make UTF-8 encoding of (say) Chinese characters work. You actually do not need to resort to using a stream. Any Chinese (or other Unicode-dependent languages) written to an ordinary Delphi string will work when assigned to TIdHTTPResponseInfo.ContentText if the CharSet property has not been accidentally undone.

于 2013-09-01T21:10:58.257 回答
1

请务必使用 UTF8编码保存您的文件。例如,使用 MyHTML 变量作为 TStringList

MyHTML.SaveToFile(HTMLFileName, TEncoding.UTF8);

它适用于我的应用程序,只不过是一个 TStringList 和这行代码。

于 2012-06-28T14:31:21.843 回答
1

我正在生成一个运行时字符串并将该字符串作为对 HTTP 服务器组件 (ICS) 的响应返回。是否可以将 TEncoding 应用于字符串?

是的。DelphiStringUnicodeStringXE 中的一个。自 D2009 以来,Delphi 就对 UTF-8 编码字符串提供了原生支持。

您可以做的一件事是将原始数据分配UnicodeString给一个UTF8String变量,然后让 RTL 为您将 Unicode 数据编码为 UTF-8,然后您可以将原始字节发送UTF8String给客户端:

var 
  myHTML: string;  
  myHTMLUtf8: UTF8String; 

myHTML := ...
myHTMLUtf8 := myHTML;
// send myHTMLUtf8 as-is...

另一种选择是将 UTF-8 数据作为TStream. 您可以将 aUTF8String放入 a TMemoryStream

var 
  myHTML: string;  
  myHTMLUtf8: UTF8String;
  strm: TMemoryStream;

myHTML := ...
myHTMLUtf8 := myHTML;

strm := TMemoryStream.Create;
strm.WriteBuffer(PAnsiChar(myHTMLUtf8)^, Length(myHTMLUtf8) * SizeOf(AnsiChar));
strm.Position := 0;
// send strm as-is...
strm.Free;

或者将原件UnicodeString放入一个TStringStream应用TEncoding.UTF8到它的地方:

var 
  myHTML: string;  
  strm: TStringStream;

myHTML := ...

strm := TStringStream.Create(myHTML, TEncoding.UTF8);
// send strm as-is...
strm.Free;
于 2012-06-28T21:24:45.770 回答
0

在发布这个问题后,我发现 HTMLEncode 函数(在 HTTPApp 单元中找到)存在一些问题,而 HTMLEscape 函数(在 HTTPUtil 单元中找到)也有同样的问题。文档没有说太多,但在使用 HTMEscape 功能重试后,浏览器显示了正确的重音。

我不知道是否有更好的方法来解决这个问题。

于 2012-06-28T17:40:29.337 回答