TStringStream型のデータを表示・加工したいのですが、うまくいきません。
取得したデータが大きすぎるためか「読み込み違反...」というメッセージが出ます。
他の型に変える方法はないのでしょうか?
(適当なメソッドはなさそうですが)
インターネットへはアクセスできて、
データもたぶん取れているようです。
Indy.Post(StrUrl,data,strRead);
ShowMessage(strRead.DataString);
失敗するので
検索エンジンのURLにしたら
エラー止まりました
接続先のURLが POSTに対応していないだけではないですか?
URL確認ください。
@さん、レスありがとうございます。
>>失敗するので
>>検索エンジンのURLにしたら
>>エラー止まりました
プログラムを見直してみたところ、パラメータの設定に間違いがありました。
結局、データの取得はできていなかったようです。
でも、修正しても同じ状況です。
>接続先のURLが POSTに対応していないだけではないですか?
POSTには対応しています。
それに、他の言語ではうまく取得できていました。
下記は、作成したプログラムの一部です。
URLの公表は、支障があるとまずいので控えさせてください。
(ごめんなさい)
POSTに対応しているホームページをいくつか探してみたのですが、
フォーマットが少し違うようです。
(フィールド名と渡す値の間が=になっていない)
//************************
procedure TForm1.Button1Click(Sender: TObject);
var
data : TIdMultiPartFormDataStream;
begin
clear_search_data();
data := comb_search_data();
post_http(data,'1');
end;
procedure TForm1.post_http(data:TIdMultiPartFormDataStream;page:String);
var
strRead:TStringStream;
Indy:TIdHTTP;
server, path, Strurl:String;
begin
strRead:= TStringStream.Create('aaa');
Indy:= TIdHTTP.Create(nil);
server := 'http://?????.???.??.jp';
path := '/???/?????/???????????????????????????page='// + page
StrUrl := server + path;
strRead := nil;
try
Indy.Post(StrUrl,data,strRead);
ShowMessage(strRead.DataString);
StatusBar1.SimpleText := 'データを取得しました';
finally
strRead.Free;
end;
end;
procedure TForm1.clear_search_data();
begin
Ggyousha := '';
Gcode := '';
end;
function TForm1.comb_search_data():TIdMultiPartFormDataStream;
var
tmp_data:TIdMultiPartFormDataStream;
begin
//Ggyousha,Gcodeは、GUIで設定
tmp_data := TIdMultiPartFormDataStream.Create;
tmp_data.AddFormField('gyousha' , Ggyousha);
tmp_data.AddFormField('code' , Gcode);
Result := test;
end;
end.
すみません、プログラムの最後から3行目が間違っていました。
>Result := test;
Result := tmp_data;
> strRead := nil;
Read Errorが出る原因はこれでしょ。
>> strRead := nil;
>Read Errorが出る原因はこれでしょ。
ありがとうございます。
サーバーからエラーメッセージが返ってくるようにはなったみたいです。
ただ、送っているパラメータがおかしいのでしょうか。
送っているパラメータの中に次の文字列が含まれており、
これがうまく送れていないようです。
'BT=M%22+target%3D%22W20%22&' + 'hyoujipage=' + page
この文字列を送るにはどのように記述すればよいのでしょうか?
ShowMessageで表示するには、&を&&にすればよいようですが、
正常なデータは送れていないようです。
>「初心者」は「名無し」と同じ
うーん。
改名しました。
「初心者2」から「ビギナー(ミムラが好き)」
何で TIdMultiPartFormDataStream を使うのかな?
>'BT=M%22+target%3D%22W20%22&' + 'hyoujipage=' + page
このまま、multipart/form-dataとしてPOSTすると、
No Argument for Format'%'エラーになってしまうはず。
'BT=M"+target="W20"&hyoujipage=' + page
このようにデコードしなければ送れない。
&記号は複数のパラメータを繋げて一つの文字列として送信する場合のセパレータ。
なので、TIdMultiPartFormDataStreamではなく、StringかStreamでPOSTした方がいいと思うけど。
ミムラよりヤンクミが好きさん、
レスありがとうございます。
>TIdMultiPartFormDataStreamではなく、StringかStreamでPOSTした方がいい>と思うけど。
できれば、パラメータはStringでPOSTしたかったのですが、
Indy.Postが(受信データを利用できるのは)
Indy.Post(Url:String;data:String;Res:TStringStream)
の形式だけだったものですから。
他の方法があるのでしょうか?
procedure Post(AURL:string; const ASource:TStrings; const AResponseContent:TStream); overload;
procedure Post(AURL:string; const ASource:TStream; const AResponseContent:TStream); overload;
procedure Post(AURL:string; const ASource:TIdMultiPartFormDataStream; AResponseContent:TStream); overload;
TidHttpのPOST手続きは3種類で、stringを使うなら一番上。
1行だけのTStringsなら、stringと同じようなもの。
だけど、1行で複数のパラメータを &記号で繋いでしまうと、
&記号が%26にデコードされちゃうのでNG。
個々のパラメータをTStringsにAddしていけば、Indyが
勝手に&記号で各パラメータを繋いでくれる。
>TidHttpのPOST手続きは3種類で、stringを使うなら一番上。
さっそく修正して、実行させましたが、エラーが発生します。
どこが間違っているのでしょうか?
何度もお手数をかけてすみませんがよろしくお願いします。
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ComCtrls, StdCtrls, IdBaseComponent,
IdComponent, IdTCPConnection, IdTCPClient, IdHTTP, IdMultiPartFormData;
type
TForm1 = class(TForm)
Memo1: TMemo;
Button1: TButton;
StatusBar1: TStatusBar;
IdHTTP1: TIdHTTP;
private
{ Private 宣言 }
procedure Button1Click(Sender: TObject);
// procedure post_http(data:TStrings;page:String);
procedure clear_search_data();
function comb_search_data():TStrings;
procedure Post(AURL:string; const ASource:TStrings; const
AResponseContent:TStream); overload; //<<<<<ここで下記のエラー発生
[エラー] TestInternetUnit1.pas(23): E2065 forward または external 宣言された 'TForm1.Post' が見つかりません
//procedure TIdHTTP.Post(AURL:string; const ASource:TStrings; const
AResponseContent:TStream); overload; //<<<<<こう変えてもだめ
> procedure Post(AURL:string; const ASource:TStrings; const
AResponseContent:TStream); overload; //<<<<<ここで下記のエラー発生
↑
idHttp.pasで宣言済みなので、自分で書く必要なし。
不凍液は入れておいた方がいいよ。まだまだ寒い日もあるし。
ミムラも、ヤンクミも、わかんないよ・・・。
テレビ見れば、いるのかな・・・。
>ミムラも、ヤンクミも、わかんないよ・・・。
>テレビ見れば、いるのかな・・・。
どちらも今は、見れません。
ゴクセンは19日に終わりましたし。
お仕事ご苦労様です。
でももうすぐ失業する私からすれば少しだけうらやましいです。
//******************
ミムラよりヤンクミが好きさんレスありがとうございます。
Delphi2005を使っているのですが、今いろいろなエラーが出て
ちょっと混乱しています。
以前のソースに戻したりしても違うエラーが出たり...
少し頭を冷やして考えてみます。
関西でないと知らないかも
>idHttp.pasで宣言済みなので、自分で書く必要なし。
コンパイルは通るようになったのですが、
実行時に(Applcation.Runのところでエラー
「不正なプロパティの値です」が出ます。
何が間違っているのでしょうか?
なお、Delphi2005を使用しています
自己レスです。
やっと原因がわかりました。
うまく動かないので、いろいろとプログラムの動作を確認しているとき、
procedure Button1Click(Sender: TObject);
をtypeのところからprivateのところに移動したのが原因のようです。
あと、次の場合はどうすればよいのでしょうか?
tmp_dataまたはdataをグローバル変数にするしかないのでしょうか?
Freeでメモリを開放するとエラーになりますし、Assiginを使ってもうまくいきません。
function TForm1.comb_search_data():TStringList;
var
tmp_data:TStringList;
begin
tmp_data := TStringList.Create;
try
tmp_data.Add('g='+ g);
tmp_data.Add('k=' + k);
finally
Result := tmp_data;
//Result.Assign(tmp_data); これにしてもエラー
// tmp_data.Free; こうしてもエラー
//両方コメントにするとエラーにならないがメモリを占有したまま
end
end;
procedure TForm1.Button1Click(Sender: TObject);
var
data : TStringList;
begin
data := TStringList.Create;
data := comb_search_data();
post_http(data,'1');
end;
end.
一般にオブジェクトを返すような関数は感心しません。呼び出し元で生成・破棄を
行うようにします。
procedure Nantoka(sl:TStringList);
begin
sl.Add('nantoka');
sl.Add('kantoka');
end;
procedure TForm1.Button1Click(Sender: TObject);
var
sl:TStringList;
begin
sl := TStringList.Create;
Nantoka(sl);
Memo1.Lines.Assign(sl);
sl.Free;
end;
>呼び出し元で生成・破棄を
>行うようにします。
りおりおさんありがとうございます。
ご指摘のとおりに修正しました。
ツイート | ![]() |