日記帳
本ページはプロモーションが含まれています
カテゴリー
Links
blog(ブログ)マスター
アンドロイドの巣
ゼロから始めるベランダ菜園
タイトル
2024年11月
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30

Win32 SJIS(〜Delphi2007? )で、Idhttp.Getすると壊れる理由

2010-12-21
Win32 SJIS(〜Delphi2007? )で、Idhttp.Getすると壊れる理由

編集:2010年12月21日
執筆:2010年12月20日

今日のお題は、?

使用したバージョン: Indy version 10.5.8

IdHttp.Get(URL)が
いつの間にか文字コードが自動変換になりました。

Delphi2009より前のDelphiでのIndy文字化け
デフォルトがencASCIIのため 文字が破壊され ? に なってしま います。
※Delphi2009以降は、UTF8で呼ばれるので、この問題はないと思います。

英文圏がデフォルトのため、
 Win32 SJISベースのDelphi(〜2007?まで)の場合は、変更が必要です。
IdGlobal.GIdDefaultAnsiEncoding := encOSDefault;
IdGlobal.GIdDefaultAnsiEncoding := encUTF8;
 のお好きなほうを、プログラムの最初や随時変更が必要なところで呼びます。
 グローバル変数なので、毎回変更がいらない場合は、1回よべば十分です。
  TIdhttpに限らず、TIdMailなどで変なときは、試してみる価値はあります。
 Delphi2009以降の最新版は、UTF8ベースなので、こういう変更はいらないと思います。

  グローバル変数をいじる方がコードの書き換えが少なくてすみます。
  画像などをIdHTTP1.Get(url)で取得していた場合は、コードを修正する必要があります。



【まとめ】
・自動変換したくない場合は、Streamを使います。
  (画像やファイルなど変更・壊れては困るデータ)
  IdHTTP1.Get(url , MemoryStream);

・SJISのDelphiの場合(SJISで扱う場合)
  (※Shift_JIS規格外の文字コードは、自動変換または、(?)になって破壊されます。)
  1) デフォルトを変更する方法
    IdGlobal.GIdDefaultAnsiEncoding := encOSDefault;
    s := IdHTTP1.Get(url);

  2) 呼ぶたびに指定する方法
    s := IdHTTP1.Get(url , TIdTextEncoding.Default);
    ※UTF8環境では、TIdTextEncodingの部分のパラメーターがないので注意。

・SJISのDelphiの場合(UTF8で扱う場合)
  1) デフォルトを変更する方法
    IdGlobal.GIdDefaultAnsiEncoding := encUTF8;
    s := IdHTTP1.Get(url);
  2) 呼ぶたびに指定する方法
    s := IdHTTP1.Get(url, TIdTextEncoding.UTF8);

・UTF8のDelphiの場合
  IdHTTP1.Get(url);

キーワード

  GIdDefaultAnsiEncoding , Indy文字化け

一覧(自動変換:個別指定)
  s := IdHTTP1.Get(url, TIdTextEncoding.Default);
  s := IdHTTP1.Get(url, TIdTextEncoding.UTF8);
一覧(自動変換:統一)
  IdGlobal.GIdDefaultAnsiEncoding := encOSDefault;
  IdGlobal.GIdDefaultAnsiEncoding := encUTF8;
  s := IdHTTP1.Get(url);
一覧(未加工)
  IdHTTP1.Get(url , MemoryStream);

コンパイラ指令を使って複数のバージョンで共有する

・コンパイラ指令(例)
  {$I IdCompilerDefines.inc}
  s := IdHTTP1.Get(url{$IFDEF STRING_IS_ANSI},TIdTextEncoding.Default{$ENDIF});
  または
  s := IdHTTP1.Get(url{$IFNDEF STRING_IS_UNICODE},TIdTextEncoding.Default{$ENDIF});
・コンパイラ指令(例)
  {$I IdCompilerDefines.inc}
  {$IFNDEF STRING_IS_UNICODE}
    IdGlobal.GIdDefaultAnsiEncoding := encOSDefault;
  {$ENDIF}
  s := IdHTTP1.Get(url);

・ {$IFNDEF UNICODE}{$ENDIF}は未調査。

おまけ : StreamをStringに強制的に入れる方法。
function StreamToString(AStream: TStream) : string;
begin
  SetLength(Result , AStream.Size);
  if (AStream.Size > 0) then
    AStream.Read(Result[1], AStream.Size);
end;

  • クッキーの消し方
    procedure TForm1.Action_ClearCookie1Execute(Sender: TObject);
    begin
      IdCookieManager1.CookieCollection.Clear;
    end;

  • クッキーを使わない
    IdHTTP1.AllowCookies := False;


脱Delphi !!
   .Netへ レッツゴー
   C# は、豊富な機能が満載 ダヨ。

pascalユーティリティベースのバグでお悩みは、
   .Netへ レッツゴー
   すっきり すっきり すっきり。



PR

[PR]