请教TIDHttp控件用法 本帖最后由 merrymin 于 2010-12-02 16:27:08 编辑 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 下面附上源码:procedure TForm1.Rzbtn1Click(Sender: TObject);var Response: TStringStream;begin with IdHTP1.Request do begin AcceptLanguage := 'zh-cn'; Referer := 'http://xxx.xxx.cn/'; AcceptEncoding := 'gzip, deflate'; UserAgent := 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022; InfoPath.2; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)'; Host := 'xxx.xxx.cn'; Connection := 'Keep-Alive'; CustomHeaders.Text := 'Set-Cookie: OXPYJ911=1207DD4D; cookies_login_state=user_id=2560F2C27F0FC02E4356D51B827A7204; ASP.NET_SessionId=zu2fmjaobt3zh055foo0xwus; AJSTAT_ok_times=28; AJSTAT_ok_pages=3'; end; try Response := TStringStream.Create(''); try IdHTP1.AllowCookies:=true; IdHTP1.Get('http://xxx.xxx.cn/ajax/xxxx HTTP/1.1', Response); Rzmm1.Text := Response.DataString; finally FreeAndNil(Response); end; except ShowMessage('Error!'); end;end;程序表现为:假死或者发送过去的消息不能产生结果 http://xxx.xxx.cn/ajax/xxxx HTTP/1.1感觉你这个地址不大对劲 这个地址用在Get方法里是正确的,我可以保证! 当然,直接打开地址是能有反应的。 但是,我现在要实现的结果是绕过IE直接发送数据包到服务器上与服务器数据库作交互,在自定义session格式上卡壳了。 procedure InitHttp();begin http := TIdHTTP.Create(nil); http.ReadTimeout := 30000; http.OnRedirect := OnRedirect; http.Request.Accept := 'image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, */*'; http.Request.AcceptLanguage := 'zh-cn'; http.Request.ContentType := 'application/x-www-form-urlencoded'; http.Request.UserAgent := 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; Maxthon; .NET CLR 1.1.4322)'; http.ProxyParams.ProxyServer := '代理服务器地址'; http.ProxyParams.ProxyPort := '代理服务器端口';end;如何取得服务端返回的cookie信息,并添加到http的request对象中procedure Setcookie;vari: Integer;tmp, cookie: String;begincookie := '';for i := 0 to http.Response.RawHeaders.Count - 1 dobegin tmp := http.Response.RawHeaders[i]; if pos('set-cookie: ', LowerCase(tmp)) = 0 then Continue; tmp := Trim(Copy(tmp, Pos('Set-cookie: ', tmp) + Length('Set-cookie: '), Length(tmp))); tmp := Trim(Copy(tmp, 0, Pos(';', tmp) - 1)); if cookie = '' then cookie := tmp else cookie := cookie + '; ' + tmp;end;if cookie <> '' thenbegin for i := 0 to http.Request.RawHeaders.Count - 1 do begin tmp := http.Request.RawHeaders[i]; if Pos('cookie', LowerCase(tmp)) = 0 then Continue; http.Request.RawHeaders.Delete(i); Break; end; http.Request.RawHeaders.Add('cookie: ' + cookie);end;end;如何取得网页中的所有连接,对代码做修改你也可以实现查找所有图片等等, QStrings.rar(79K) (点击下载)在这里推荐使用QString来实现文本替换、查找等功能,附件里有下载。function GetURLList(Data: String): TStringList;vari: Integer;List: TStringList;tmp: String;function Split(Data, Node: String): TStringList;var Count, i, j: Integer; function GetFieldCount(Data, Node: String): Integer; var i: Integer; begin Result := -1; i := Pos(Node, Data); if i = 0 then Exit; Result := 0; while i <> 0 do begin Inc(Result); Delete(Data, 1, i + Length(Node) - 1); i := Pos(Node, Data); end; end;beginResult := TStringList.Create;Count := GetFieldCount(Data, Node);for i := 0 to Count - 1 dobegin j := Pos(Node, Data); Result.Add(Copy(Data, 1, j - 1)); Delete(Data, 1, j + Length(Node) - 1);end;Result.Add(Data);end;beginResult := TStringList.Create;try List := split(Data, 'href='); for i := 1 to List.Count - 1 do begin tmp := List[i]; tmp := Copy(tmp, 0, Pos('</a>', tmp) - 1); tmp := Copy(tmp, 0, Pos('>', tmp) - 1); if Pos(' ', tmp) <> 0 then tmp := Copy(tmp, 0, Pos(' ', tmp) - 1); tmp := Q_ReplaceStr(tmp, Char(34), ''); tmp := Q_ReplaceStr(tmp, Char(39), ''); if not Compare(CI.Key, tmp) then Continue; if Copy(tmp, 1, 7) <> 'http://' then begin if Copy(tmp, 1, 1) = '.' then tmp := StringReplace(tmp, '.', '', []); if Copy(tmp, 1, 1) = '.' then tmp := StringReplace(tmp, '.', '', []); try tmp := 'http://' + http.URL.Host + ':' + http.URL.Port + http.URL.Path + tmp; except end; end; if Result.IndexOf(tmp) <> -1 then Continue; Result.Add(tmp); end; FreeAndNil(List);exceptend;end;如何模拟http的get方法打开一个网页function GetMethod(http: TIDhttp; URL: String; Max: Integer): String;varRespData: TStringStream;beginRespData := TStringStream.Create('');try try Http.Get(URL, RespData); Http.Request.Referer := URL; Result := RespData.DataString; except Dec(Max); if Max = 0 then begin Result := ''; Exit; end; Result := GetMethod(http, URL, Max); end;finally FreeAndNil(RespData);end;end;如何模拟http的post方法提交一个网页function PostMethod(URL, Data: String; max: Integer): String;varPostData, RespData: TStringStream;beginRespData := TStringStream.Create('');PostData := TStringStream.Create(Data);try try if http = nil then Exit; Http.Post(URL, PostData, RespData); Result := RespData.DataString; http.Request.Referer := URL; except Dec(Max); if Max = 0 then begin Result := ''; Exit; end; Result := PostMethod(URL, Data, Max); end;finally http.Disconnect; FreeAndNil(RespData); FreeAndNil(PostData);end;end; 也可參考這裡: http://hi.baidu.com/zhxp/blog/item/b548968fd2ea76f0513d9238.html 您给的地址我仔细看过了,但是: 这里Setcookie方法需要调用到response(反应回来)的数据,是request(发送请求)之后才能获取到的,但是现在的情况是request需要自定义Session,而不是使用返回回来的session。 我是这样理解的,请问是这样的吗?如果是这样,那又改怎么解决这个问题呢? 先抓包看看你程序GET到的信息,如果程序不能执行,先简化检查一下,如果可以执行抓包看看GET的信息。varIECook : string;IECook := 'OXPYJ911=1207DD4D; cookies_login_state=user_id=2560F2C27F0FC02E4356D51B827A7204; ASP.NET_SessionId=zu2fmjaobt3zh055foo0xwus; AJSTAT_ok_times=28; AJSTAT_ok_pages=3'; IdHTTP1.Request.UserAgent:='Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022; InfoPath.2; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)'; IdHTTP1.Request.Accept := '*/*'; IdHTTP1.Request.AcceptLanguage := 'zh-cn'; IdHTTP1.Request.AcceptEncoding := 'gzip, deflate'; IdHTTP1.Request.Connection := 'Keep-Alive'; IdHTTP1.Request.CacheControl := 'no-cache'; IdHTTP1.Request.Referer:='http://xxx.xxx.cn/'; IdHTTP1.Request.CustomHeaders.Text := 'Cookie: ' + IECook; IdHTTP1.HTTPOptions:=IdHTTP1.HTTPOptions+[hoKeepOrigProtocol]; IdHTTP1.ProtocolVersion:=pv1_1; Memo1.text := IDhttp1.Get(URL.Text); 调试结果如下:Get数据包能发送出去,但是接受不到结果。可能产生此情况的原因是:Cookie还是没有设置好! procedure TForm1.Button1Click(Sender: TObject);begin WebBrowser1.Navigate(Edit1.Text);end;procedure TForm1.WebBrowser1DocumentComplete(ASender: TObject; const pDisp: IDispatch; var URL: OleVariant);begin memo1.Clear; memo1.Text:=(WebBrowser1.document as ihtmldocument2).cookie; //要引用 Mshtml,end;procedure TForm1.Button2Click(Sender: TObject);var buf: array[0..1024*4-1] of Char; size: DWORD;begin memo2.Clear; InternetGetCookie(PChar(Edit1.Text), nil, buf, size); //要引用 wininet, memo2.Text := buf;end;将memo1或者memo2内cookie赋值给IECook测试一下IdHTTP1.Request.CustomHeaders.Text := 'Cookie: ' + IECook;如果方便的话可以发网地址给:dongmei757 @ gmail.com ,帮你测试一下。 WebBrowser1与InternetGetCookie,不一定能取到Cookie,如果Set-Cookie: 为HttpOnly就取不到了 memo1.Text:=(WebBrowser1.document as ihtmldocument2).cookie; 可以获得当前WEB的cookie但不知道使用idhttp后,获得的网页内容是否一致。 通过不断调试,终于发现bug所在:Cookie的标准格式应该为: 'Cookie: XXXXX',否则发送出去的数据包是接受不到相应的recv数据的。谢谢各位的解答! 有人用过DSpack吗? 如何判断一个软件运行完毕 大家帮忙看看哪里错了? 模态窗体关闭问题,大家救救急! 在dbgrid里如何加入一列 烦死了,ImeName,ImeMode这两个厮太烦人了。 100分! EXCEL 里怎么实现,通过下拉菜单选择另外一个EXCEL文件中某列的值 问一个查询的问题,很简单的 关于tcombobox取数据库记录的简单问题。 成为Delphi高手必须去的地方! 为何delphi 的父体窗上的图片无法继承 StringGrid 数据插入数据库表
var
Response: TStringStream;
begin
with IdHTP1.Request do
begin
AcceptLanguage := 'zh-cn';
Referer := 'http://xxx.xxx.cn/';
AcceptEncoding := 'gzip, deflate';
UserAgent := 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022; InfoPath.2; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)';
Host := 'xxx.xxx.cn';
Connection := 'Keep-Alive';
CustomHeaders.Text := 'Set-Cookie: OXPYJ911=1207DD4D; cookies_login_state=user_id=2560F2C27F0FC02E4356D51B827A7204; ASP.NET_SessionId=zu2fmjaobt3zh055foo0xwus; AJSTAT_ok_times=28; AJSTAT_ok_pages=3';
end;
try
Response := TStringStream.Create('');
try
IdHTP1.AllowCookies:=true;
IdHTP1.Get('http://xxx.xxx.cn/ajax/xxxx HTTP/1.1', Response);
Rzmm1.Text := Response.DataString;
finally
FreeAndNil(Response);
end;
except
ShowMessage('Error!');
end;
end;
程序表现为:假死或者发送过去的消息不能产生结果
感觉你这个地址不大对劲
这个地址用在Get方法里是正确的,我可以保证!
当然,直接打开地址是能有反应的。
但是,我现在要实现的结果是绕过IE直接发送数据包到服务器上与服务器数据库作交互,在自定义session格式上卡壳了。
begin
http := TIdHTTP.Create(nil);
http.ReadTimeout := 30000;
http.OnRedirect := OnRedirect;
http.Request.Accept := 'image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, */*';
http.Request.AcceptLanguage := 'zh-cn';
http.Request.ContentType := 'application/x-www-form-urlencoded';
http.Request.UserAgent := 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; Maxthon; .NET CLR 1.1.4322)'; http.ProxyParams.ProxyServer := '代理服务器地址';
http.ProxyParams.ProxyPort := '代理服务器端口';
end;如何取得服务端返回的cookie信息,并添加到http的request对象中procedure Setcookie;
var
i: Integer;
tmp, cookie: String;
begin
cookie := '';
for i := 0 to http.Response.RawHeaders.Count - 1 do
begin
tmp := http.Response.RawHeaders[i];
if pos('set-cookie: ', LowerCase(tmp)) = 0 then Continue;
tmp := Trim(Copy(tmp, Pos('Set-cookie: ', tmp) + Length('Set-cookie: '), Length(tmp)));
tmp := Trim(Copy(tmp, 0, Pos(';', tmp) - 1));
if cookie = '' then cookie := tmp else cookie := cookie + '; ' + tmp;
end;
if cookie <> '' then
begin
for i := 0 to http.Request.RawHeaders.Count - 1 do
begin
tmp := http.Request.RawHeaders[i];
if Pos('cookie', LowerCase(tmp)) = 0 then Continue;
http.Request.RawHeaders.Delete(i);
Break;
end;
http.Request.RawHeaders.Add('cookie: ' + cookie);
end;
end;
如何取得网页中的所有连接,对代码做修改你也可以实现查找所有图片等等, QStrings.rar(79K) (点击下载)在这里推荐使用QString来实现文本替换、查找等功能,附件里有下载。function GetURLList(Data: String): TStringList;
var
i: Integer;
List: TStringList;
tmp: String;function Split(Data, Node: String): TStringList;
var
Count, i, j: Integer;
function GetFieldCount(Data, Node: String): Integer;
var
i: Integer;
begin
Result := -1;
i := Pos(Node, Data);
if i = 0 then Exit;
Result := 0;
while i <> 0 do
begin
Inc(Result);
Delete(Data, 1, i + Length(Node) - 1);
i := Pos(Node, Data);
end;
end;
begin
Result := TStringList.Create;
Count := GetFieldCount(Data, Node);
for i := 0 to Count - 1 do
begin
j := Pos(Node, Data);
Result.Add(Copy(Data, 1, j - 1));
Delete(Data, 1, j + Length(Node) - 1);
end;
Result.Add(Data);
end;
begin
Result := TStringList.Create;
try
List := split(Data, 'href=');
for i := 1 to List.Count - 1 do
begin
tmp := List[i];
tmp := Copy(tmp, 0, Pos('</a>', tmp) - 1);
tmp := Copy(tmp, 0, Pos('>', tmp) - 1);
if Pos(' ', tmp) <> 0 then tmp := Copy(tmp, 0, Pos(' ', tmp) - 1);
tmp := Q_ReplaceStr(tmp, Char(34), '');
tmp := Q_ReplaceStr(tmp, Char(39), '');
if not Compare(CI.Key, tmp) then Continue;
if Copy(tmp, 1, 7) <> 'http://' then
begin
if Copy(tmp, 1, 1) = '.' then tmp := StringReplace(tmp, '.', '', []);
if Copy(tmp, 1, 1) = '.' then tmp := StringReplace(tmp, '.', '', []);
try
tmp := 'http://' + http.URL.Host + ':' + http.URL.Port + http.URL.Path + tmp;
except
end;
end;
if Result.IndexOf(tmp) <> -1 then Continue;
Result.Add(tmp);
end;
FreeAndNil(List);
exceptend;
end;
如何模拟http的get方法打开一个网页function GetMethod(http: TIDhttp; URL: String; Max: Integer): String;
var
RespData: TStringStream;
begin
RespData := TStringStream.Create('');
try
try
Http.Get(URL, RespData);
Http.Request.Referer := URL;
Result := RespData.DataString;
except
Dec(Max);
if Max = 0 then
begin
Result := '';
Exit;
end;
Result := GetMethod(http, URL, Max);
end;
finally
FreeAndNil(RespData);
end;
end;如何模拟http的post方法提交一个网页function PostMethod(URL, Data: String; max: Integer): String;
var
PostData, RespData: TStringStream;
begin
RespData := TStringStream.Create('');
PostData := TStringStream.Create(Data);
try
try
if http = nil then Exit;
Http.Post(URL, PostData, RespData);
Result := RespData.DataString;
http.Request.Referer := URL;
except
Dec(Max);
if Max = 0 then
begin
Result := '';
Exit;
end;
Result := PostMethod(URL, Data, Max);
end;
finally
http.Disconnect;
FreeAndNil(RespData);
FreeAndNil(PostData);
end;
end;
您给的地址我仔细看过了,但是: 这里Setcookie方法需要调用到response(反应回来)的数据,是request(发送请求)之后才能获取到的,但是现在的情况是request需要自定义Session,而不是使用返回回来的session。
我是这样理解的,请问是这样的吗?如果是这样,那又改怎么解决这个问题呢?
先抓包看看你程序GET到的信息,如果程序不能执行,先简化检查一下,如果可以执行抓包看看GET的信息。
var
IECook : string;IECook := 'OXPYJ911=1207DD4D; cookies_login_state=user_id=2560F2C27F0FC02E4356D51B827A7204; ASP.NET_SessionId=zu2fmjaobt3zh055foo0xwus; AJSTAT_ok_times=28; AJSTAT_ok_pages=3';
IdHTTP1.Request.UserAgent:='Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022; InfoPath.2; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)';
IdHTTP1.Request.Accept := '*/*';
IdHTTP1.Request.AcceptLanguage := 'zh-cn';
IdHTTP1.Request.AcceptEncoding := 'gzip, deflate';
IdHTTP1.Request.Connection := 'Keep-Alive';
IdHTTP1.Request.CacheControl := 'no-cache';
IdHTTP1.Request.Referer:='http://xxx.xxx.cn/';
IdHTTP1.Request.CustomHeaders.Text := 'Cookie: ' + IECook;
IdHTTP1.HTTPOptions:=IdHTTP1.HTTPOptions+[hoKeepOrigProtocol];
IdHTTP1.ProtocolVersion:=pv1_1;
Memo1.text := IDhttp1.Get(URL.Text);
调试结果如下:
Get数据包能发送出去,但是接受不到结果。可能产生此情况的原因是:Cookie还是没有设置好!
procedure TForm1.Button1Click(Sender: TObject);
begin
WebBrowser1.Navigate(Edit1.Text);
end;procedure TForm1.WebBrowser1DocumentComplete(ASender: TObject;
const pDisp: IDispatch; var URL: OleVariant);
begin
memo1.Clear;
memo1.Text:=(WebBrowser1.document as ihtmldocument2).cookie; //要引用 Mshtml,end;procedure TForm1.Button2Click(Sender: TObject);
var
buf: array[0..1024*4-1] of Char;
size: DWORD;
begin
memo2.Clear;
InternetGetCookie(PChar(Edit1.Text), nil, buf, size); //要引用 wininet,
memo2.Text := buf;
end;
将memo1或者memo2内cookie赋值给IECook测试一下IdHTTP1.Request.CustomHeaders.Text := 'Cookie: ' + IECook;如果方便的话可以发网地址给:dongmei757 @ gmail.com ,帮你测试一下。
Cookie的标准格式应该为: 'Cookie: XXXXX',否则发送出去的数据包是接受不到相应的recv数据的。
谢谢各位的解答!