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 で試してみましたが、結果は同じです。HTTP 要求を処理するために ICS コンポーネントを使用しています。

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 に書き込んだ内容が失われます。

言い換えれば:(与えられた Info: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!

実際、(たとえば) 漢字の UTF-8 エンコーディングを機能させるために、(Info.ContentText への書き込み以外に) 何もしなければならないことはありません。実際には、ストリームを使用する必要はありません。CharSet プロパティが誤って元に戻されていない場合、通常の Delphi 文字列に書き込まれた中国語 (またはその他の Unicode 依存言語) は、TIdHTTPResponseInfo.ContentText に割り当てられたときに機能します。

于 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 の です。Delphi は、D2009 以降、UTF-8 でエンコードされた文字列をネイティブでサポートしています。

できることの 1 つは、元のデータUnicodeStringUTF8String変数に代入し、RTL で Unicode データを UTF-8 にエンコードすることです。その後、生のバイトをUTF8Stringクライアントに送信できます。

var 
  myHTML: string;  
  myHTMLUtf8: UTF8String; 

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

もう 1 つのオプションは、UTF-8 データを として送信することTStreamです。UTF8Stringaを 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;

または、オリジナルをそれに適用された に配置UnicodeStringTStringStreamます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 に答える