Win32 SJIS(〜Delphi2007? )で、Idhttp.Getすると壊れる理由
カテゴリー: ぷろぐらみんぐ/Indy
2010-12-21
Win32 SJIS(〜Delphi2007? )で、Idhttp.Getすると壊れる理由
今日のお題は、?
使用したバージョン: Indy version 10.5.8
IdHttp.Get(URL)が
いつの間にか文字コードが自動変換になりました。
Delphi2009より前のDelphiでのIndy文字化け
デフォルトがencASCIIのため 文字が破壊され ? に なってしま います。
※Delphi2009以降は、UTF8で呼ばれるので、この問題はないと思います。
英文圏がデフォルトのため、
Win32 SJISベースのDelphi(〜2007?まで)の場合は、変更が必要です。
グローバル変数なので、毎回変更がいらない場合は、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);
一覧(自動変換:個別指定)
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に強制的に入れる方法。
脱Delphi !!
.Netへ レッツゴー
C# は、豊富な機能が満載 ダヨ。
pascalユーティリティベースのバグでお悩みは、
.Netへ レッツゴー
すっきり すっきり すっきり。
編集: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;
のお好きなほうを、プログラムの最初や随時変更が必要なところで呼びます。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;
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へ レッツゴー
すっきり すっきり すっきり。