首先说下我的目的,我需要程序通过模拟提交web表单到上传页面的方式来上传一个文件到服务器
需要模拟的页面是这个
http://darx.vicp.net/program/screen/up.html
目标页面为http://darx.vicp.net/program/screen/file.php?step=upfile
该页面会把所提交的表单的各个参数都打印出来~我在网上先找了些例子~使用Indy的HTTP控件来进行开发~源代码如下
procedure TForm1.Button1Click(Sender: TObject);
var
Request : TMemoryStream;
FileData : TMemoryStream;
Response : TStringStream;
tempArray : array[0..10000] of char;
tempString : String;
strFileSize : String;
InFile : String;
const
NewLine = chr(13) + chr(10);
begin
Screen.Cursor := crHourGlass;
InFile := 'c:\131990.jpeg';
// Set the properties for HTTP HTTP.ProtocolVersion := pv1_1;
HTTP.Request.Username := '';
HTTP.Request.Password := '';
HTTP.Request.ContentEncoding := 'multipart/form-data;boundary=-----------------------------7cf87224d2020a';
HTTP.AllowCookies := true; try
// create streams
Response := TStringStream.Create('');
Request := TMemoryStream.Create;
FileData := TMemoryStream.Create; // load file data
FileData.LoadFromFile( InFile );
FileData.Seek( 0, soFromBeginning );
// copy form data
TempString := '';
TempString := TempString + '-----------------------------7cf87224d2020a' + NewLine;
TempString := TempString + 'Content-Disposition: form-data; name="userfile"; filename="' + InFile + '"' + NewLine;
TempString := TempString + 'Content-Type: application/octet-stream' + NewLine + NewLine; // Add data to post
FillChar( temparray, SizeOf( temparray ), #0 );
strpcopy( temparray, tempstring );
Request.Write( temparray, length(tempstring) );
Request.Seek( 0, soFromEnd );
//Load FileData
Request.CopyFrom( FileData, FileData.Size );
rc1.Text := TempString;
// copy form data
TempString := '';
TempString := TempString + NewLine;
TempString := TempString + '-----------------------------7cf87224d2020a' + NewLine;
TempString := TempString + 'Content-Disposition: form-data; name="Submit"' + NewLine + NewLine; TempString := TempString + 'Submit' + NewLine;
TempString := TempString + '-----------------------------7cf87224d2020a--' + NewLine;
// Add data to post
FillChar( temparray, SizeOf( temparray ), #0 );
strpcopy( temparray, tempstring );
Request.Write( temparray, length(tempstring) );
// post file
try
HTTP.Post( 'http://darx.vicp.net/program/screen/file.php?step=upfile', Request, Response);
except
showmessage( 'Failed!')
end;
// write out debug text
rc2.Text := Response.DataString;
Request.SaveToFile('c:\test.txt'); finally
Response.Free;
Request.Free;
FileData.Free;
Screen.Cursor := crDefault;
end;
end;
可是确无法成功,返回的结果是:
<pre>Array
(
[step] => upfile
)
</pre><pre>Array
(
)
</pre>
可见一个表单项都没有提交上去.
后来使用抓包工具对比了ie提交的数据和我提交的数据,发现HTTP Request Header都不一样
IE's Request Header:
POST /program/screen/file.php?step=upfile HTTP/1.1
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/x-shockwave-flash, */*
Referer: http://darx.vicp.net/program/screen/up.html
Accept-Language: zh-cn
Content-Type: multipart/form-data; boundary=---------------------------7d4293355102ce
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; Maxthon; Poco 0.31; .NET CLR 1.1.4322; .NET CLR 2.0.40607)
Host: darx.vicp.net
Content-Length: 2095
Connection: Keep-Alive
Cache-Control: no-cacheMy Request Header:
POST /program/screen/file.php?step=upfile HTTP/1.0
Connection: keep-alive
Content-Encoding: multipart/form-data;boundary=-----------------------------7cf87224d2020a
Content-Type: text/html
Content-Length: 1997
Host: darx.vicp.net
Accept: text/html, */*
User-Agent: Mozilla/3.0 (compatible; Indy Library)
非常惊讶.居然是用的HTTP1.0的协议.可是我明明设置了
HTTP.ProtocolVersion := pv1_1;
难道是Indy的bug?!
不解.第一次用Indy,希望有过经验的同志指点一下~谢谢!
(我用的是Delphi7 使用其自带的Indy控件)
需要模拟的页面是这个
http://darx.vicp.net/program/screen/up.html
目标页面为http://darx.vicp.net/program/screen/file.php?step=upfile
该页面会把所提交的表单的各个参数都打印出来~我在网上先找了些例子~使用Indy的HTTP控件来进行开发~源代码如下
procedure TForm1.Button1Click(Sender: TObject);
var
Request : TMemoryStream;
FileData : TMemoryStream;
Response : TStringStream;
tempArray : array[0..10000] of char;
tempString : String;
strFileSize : String;
InFile : String;
const
NewLine = chr(13) + chr(10);
begin
Screen.Cursor := crHourGlass;
InFile := 'c:\131990.jpeg';
// Set the properties for HTTP HTTP.ProtocolVersion := pv1_1;
HTTP.Request.Username := '';
HTTP.Request.Password := '';
HTTP.Request.ContentEncoding := 'multipart/form-data;boundary=-----------------------------7cf87224d2020a';
HTTP.AllowCookies := true; try
// create streams
Response := TStringStream.Create('');
Request := TMemoryStream.Create;
FileData := TMemoryStream.Create; // load file data
FileData.LoadFromFile( InFile );
FileData.Seek( 0, soFromBeginning );
// copy form data
TempString := '';
TempString := TempString + '-----------------------------7cf87224d2020a' + NewLine;
TempString := TempString + 'Content-Disposition: form-data; name="userfile"; filename="' + InFile + '"' + NewLine;
TempString := TempString + 'Content-Type: application/octet-stream' + NewLine + NewLine; // Add data to post
FillChar( temparray, SizeOf( temparray ), #0 );
strpcopy( temparray, tempstring );
Request.Write( temparray, length(tempstring) );
Request.Seek( 0, soFromEnd );
//Load FileData
Request.CopyFrom( FileData, FileData.Size );
rc1.Text := TempString;
// copy form data
TempString := '';
TempString := TempString + NewLine;
TempString := TempString + '-----------------------------7cf87224d2020a' + NewLine;
TempString := TempString + 'Content-Disposition: form-data; name="Submit"' + NewLine + NewLine; TempString := TempString + 'Submit' + NewLine;
TempString := TempString + '-----------------------------7cf87224d2020a--' + NewLine;
// Add data to post
FillChar( temparray, SizeOf( temparray ), #0 );
strpcopy( temparray, tempstring );
Request.Write( temparray, length(tempstring) );
// post file
try
HTTP.Post( 'http://darx.vicp.net/program/screen/file.php?step=upfile', Request, Response);
except
showmessage( 'Failed!')
end;
// write out debug text
rc2.Text := Response.DataString;
Request.SaveToFile('c:\test.txt'); finally
Response.Free;
Request.Free;
FileData.Free;
Screen.Cursor := crDefault;
end;
end;
可是确无法成功,返回的结果是:
<pre>Array
(
[step] => upfile
)
</pre><pre>Array
(
)
</pre>
可见一个表单项都没有提交上去.
后来使用抓包工具对比了ie提交的数据和我提交的数据,发现HTTP Request Header都不一样
IE's Request Header:
POST /program/screen/file.php?step=upfile HTTP/1.1
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/x-shockwave-flash, */*
Referer: http://darx.vicp.net/program/screen/up.html
Accept-Language: zh-cn
Content-Type: multipart/form-data; boundary=---------------------------7d4293355102ce
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; Maxthon; Poco 0.31; .NET CLR 1.1.4322; .NET CLR 2.0.40607)
Host: darx.vicp.net
Content-Length: 2095
Connection: Keep-Alive
Cache-Control: no-cacheMy Request Header:
POST /program/screen/file.php?step=upfile HTTP/1.0
Connection: keep-alive
Content-Encoding: multipart/form-data;boundary=-----------------------------7cf87224d2020a
Content-Type: text/html
Content-Length: 1997
Host: darx.vicp.net
Accept: text/html, */*
User-Agent: Mozilla/3.0 (compatible; Indy Library)
非常惊讶.居然是用的HTTP1.0的协议.可是我明明设置了
HTTP.ProtocolVersion := pv1_1;
难道是Indy的bug?!
不解.第一次用Indy,希望有过经验的同志指点一下~谢谢!
(我用的是Delphi7 使用其自带的Indy控件)
解决方案 »
- edit的问题,可能比较奇怪
- 急!!!一个api函数的调用
- 关于平推打印机,打印存折和连续纸的设置.
- 请问我要将一个label的caption传到adotable中的某个字段的某一个记录中
- 500分!!急——怎么样把全屏的游戏窗体设置成为自己程序的父窗体
- 程序员的明天:各位大虾给点建议吧,不想写程序了,想去做销售或者是实施!!!!
- 用TClinetDataSet做主从表出现如下错误:Field index out of range.
- 好玩的问题。小技巧!
- 如何解决小球移动时的 闪烁?
- 怎样实现整个屏幕或某个窗体的晃动?
- 讨论:做进销存系统,批更新和事务处理的结合,什么方法更好些
- 怎么让窗体小图片的背景重复显示布满窗体?
procedure TForm1.btnGoClick(Sender: TObject);
var
Source: TMemoryStream;
Response: TStringStream;
begin
// Add the URL to the combo-box.
if cbURL.Items.IndexOf(cbURL.Text) = -1 then
cbURL.Items.Add(cbURL.Text);
Screen.Cursor := crHourGlass;
btnStop.Enabled := True;
btnGo.Enabled := False;
try
memoHTML.Clear;
// Set the properties for HTTP
HTTP.Request.Username := edUsername.Text;
HTTP.Request.Password := edPassword.Text;
HTTP.Request.ProxyServer := edProxyServer.Text;
HTTP.Request.ProxyPort := StrToIntDef(edProxyPort.Text, 80);
HTTP.Request.ContentType := edContentType.Text;
if cbSSL.Checked then
begin
HTTP.Intercept := SSL;
end
else
HTTP.Intercept := nil;
case cbMethod.ItemIndex of
0: // Head
begin
HTTP.Head(cbURL.Text);
memoHTML.Lines.Add('This is an example of some of the headers returned: ');
memoHTML.Lines.Add('---------------------------------------------------');
memoHTML.Lines.Add('Content-Type: ' + HTTP.Response.ContentType);
memoHTML.Lines.Add('Date: ' + DatetoStr(HTTP.Response.Date));
memoHTML.Lines.Add('');
memoHTML.Lines.Add('You can view all the headers by examining HTTP.Response');
end;
1: // Get
begin
memoHTML.Lines.Text := HTTP.Get(cbURL.Text);
end;
2: // Post
begin
Response := TStringStream.Create('');
try
if not bPostFile then
HTTP.Post(cbURL.Text, mePostData.Lines, Response)
else
begin
Source := TMemoryStream.Create;
try
Source.LoadFromFile(edPostFile.Text);
HTTP.Post(cbURL.Text, Source, Response);
finally
Source.Free;
end;
end;
memoHTML.Lines.Text := Response.DataString;
finally
Response.Free;
end;
end;
end;
finally
Screen.Cursor := crDefault;
btnStop.Enabled := False;
btnGo.Enabled := True;
end;
end;
http://www.delphibox.com/article.asp?articleid=109Demo:
http://www.delphibox.com/article.asp?articleid=1262这里还有一个不是用Indy控件做的Http上传文件的源码,你参考一下:
http://www.delphibox.com/article.asp?articleid=1528
我也找到了..不过也没用.协议是HTTP1.0的.
demo也很奇怪..简单的离谱..
郁闷啊..
你参照这段代码。
procedure TForm1.SendPostData;
Const
CRLF = #13#10;
Var
aStream: TMemoryStream;
Params: TMemoryStream;
S: String;
begin
aStream := TMemoryStream.create;
Params := TMemoryStream.Create; HTTP.Request.ContentType := 'multipart/form-data;
boundary=-----------------------------7cf87224d2020a'; try
S := '-----------------------------7cf87224d2020a' + CRLF +
'Content-Disposition: form-data; name="file1"; filename="c:abc.txt"' +
CRLF +
'Content-Type: text/plain' + CRLF + CRLF +
'file one content. Contant-Type can be application/octet-stream or if
you want you can ask your OS fot the exact type.' + CRLF +
'-----------------------------7cf87224d2020a' + CRLF +
'Content-Disposition: form-data; name="sys_return_url2"' + CRLF + CRLF +
'hello2' + CRLF +
'-----------------------------7cf87224d2020a--'; Params.Write(S[1], Length(S)); with HTTP do begin
try
HTTP.Post('http://www.mydomain.com/postexampe.cgi', Params,
aStream);
except
on E: Exception do
showmessage('Error encountered during POST: ' + E.Message);
end;
end;
aStream.WriteBuffer(#0' ', 1);
showmessage(PChar(aStream.Memory));
except
end;
end;
mps : TIdMultipartFormData;
begin
mps:=TIdMultipartFormData.Create;
mps.AddFile('aFile','c:\aaa.doc');
idHTTP1.Post('http://darx.vicp.net/program/screen/file.php?step=upfile',mps);
...
end;