如何通过HTTP协议上传和下载文件(100分)

D

Dlp

Unregistered / Unconfirmed
GUEST, unregistred user!
WEB服务器位于公网上,客户端只能通过HTTP协议访问该资源(其他端口都屏蔽了),
现在想用HTTP控件将文件上传到服务器上(仿照WEB页面提交的方式),我打算用Indy或者
ICS孔件完成,现在存在如下问题:
1.HTTP的POST方法怎样写,主要是文件流
2.用网页上传的方式一般要写上enctype="multipart/form-data",请问用HTTP孔件怎样
表达
3.网页上传页面的<input type="file">语句怎样实现

呵呵,请高手踊跃发言!!!
 
38. 用 WinSock 控件下载文件
1 增加一个 Winsock 控件, 名称为 Winsock1。
2 建立连接:
Winsock1.RemoteHost = "nease.com"
Winsock1.RemotePort = 80
Winsock1.Connect
3 在Winsock1.Connect 事件中加入:
Dim strCommand as String
Dim strWebPage as String
strWebPage = "http://www.nease.com/~kenj/index.html"
strCommand = "GET " + strWebPage + " HTTP/1.0" + vbCrLf
strCommand = strCommand + "Accept: */*" + vbCrLf
strCommand = strCommand + "Accept: text/html" + vbCrLf
strCommand = strCommand + vbCrLf
Winsock1.SendData strCommand
4 Winsock 开始下载, 在收到数据时, 发生DataArrival 事件。
Dim webData As String
Winsock1.GetData webData, vbString
TxtWebPage.Text = TxtWebPage.Text + webData


以下是 API 的POST 道理应该一样,你参考一下:

48. 调用winInet API接口post数据到指定的url
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
Const INTERNET_OPEN_TYPE_PRECONFIG = 0;
INTERNET_SERVICE_HTTP = 3;
INTERNET_DEFAULT_HTTP_PORT = 80;
INTERNET_FLAG_RELOAD = $80000000;
HTTP_ADDREQ_FLAG_ADD = $20000000;
HTTP_ADDREQ_FLAG_REPLACE = $80000000;
Function InternetOpen(
lpszCallerName:pchar;
dwAccessType:dword;
lpszProxyName,
lpszProxyBypass:pchar;
dwFlags:dword)
:DWord;stdcall;external 'wininet.dll' name 'InternetOpenA';

Function InternetConnect(
hInternetSession:dword;
lpszServerName:pchar;
nProxyPort:Integer;
lpszUsername,lpszPassword:pchar;
dwService,dwFlags,dwContext:dword)
:integer;stdcall;external 'wininet.dll' name 'InternetConnectA';

Function InternetReadFile(hFile:Thandle;sBuffer:pointer;
lNumBytesToRead:dword;
var lNumberOfBytesRead:Dword)
:integer;stdcall;external 'wininet.dll';

Function HttpOpenRequest(
hInternetSession:integer;
lpszVerb,
lpszObjectName,
lpszVersion,
lpszReferer:pchar;
lpszAcceptTypes:pdword;
dwFlags,dwContext:dword)
:integer;stdcall;external 'wininet.dll' name 'HttpOpenRequestA';

Function HttpSendRequest(
hHttpRequest:dword;
sHeaders:pchar;
lHeadersLength:dword;
sOptional:pchar;
lOptionalLength:dword)
:Boolean;stdcall;external 'wininet.dll' name 'HttpSendRequestA';

Function InternetCloseHandle(hInternetHandle:dword)
:Boolean;stdcall;external 'wininet.dll';

Function HttpAddRequestHeaders(
hHttpRequest:dword;
sHeaders:pchar;
lHeadersLength,lModifiers:dword)
:Boolean;stdcall;external 'wininet.dll' name 'HttpAddRequestHeadersA';
//////////////////////////////////
Function PostInfo(srv:string; port:dword; script, postdat:string):String;
var
hInternetOpen,hInternetConnect,hHttpOpenRequest:dword;
bRet,bDoLoop:Boolean;
sHeader,lpszPostData,sBuffer:String;
lPostDataLen,lNumberOfBytesRead:dword;
sReadBuffer:Array[0..4095] of char;

begin

//'Use registry access settings.
hInternetOpen:= InternetOpen('http generic',
INTERNET_OPEN_TYPE_PRECONFIG,
nil,nil,0);
If (hInternetOpen <> 0) Then
begin
showmessage('Internetopen Ok:'+inttoHex(hInternetOpen,8));
//'Type of service to access.
//'Change the server to your server name

hInternetConnect:= InternetConnect(hInternetOpen,
pchar(srv),port,nil,nil,
INTERNET_SERVICE_HTTP,0,0);
If (hInternetConnect <> 0) Then
begin
showmessage('InternetConnect Ok:'+inttoHex(hInternetConnect,8));
//'Brings the data across the wire even if it locally cached.
hHttpOpenRequest:= HttpOpenRequest(hInternetConnect,
'POST',pchar(script),'HTTP/1.0',
nil,nil,INTERNET_FLAG_RELOAD,0);
If (hHttpOpenRequest <> 0) Then
begin
showmessage('HttpOpenRequest Ok:'+inttoHex(hHttpOpenRequest,8));
sHeader:='Content-Type: application/x-www-form-urlencoded'#13#10;
bRet:= HttpAddRequestHeaders(hHttpOpenRequest,
pchar(sHeader), Length(sHeader),
HTTP_ADDREQ_FLAG_REPLACE Or HTTP_ADDREQ_FLAG_ADD);

Result:='';
if bRet then
begin
showmessage('Ok1');
lpszPostData := postdat;
lPostDataLen := Length(lpszPostData);
bRet := HttpSendRequest(hHttpOpenRequest,nil,0,
pchar(lpszPostData),lPostDataLen);

if bRet then
begin
showmessage('Ok2');
bDoLoop := True;
sReadBuffer:='';
While bDoLoop do
begin
//showmessage(inttostr(Length(sReadBuffer))); 2049 Ok
bDoLoop := InternetReadFile(hHttpOpenRequest,
@sReadBuffer, Length(sReadBuffer), lNumberOfBytesRead)<>0;
sBuffer := sBuffer+copy(sReadBuffer,1,lNumberOfBytesRead);
If (lNumberOfBytesRead=0) Then bDoLoop := False;
end;
Result:= sBuffer;
end;
End;
InternetCloseHandle(hHttpOpenRequest);
end;
InternetCloseHandle(hInternetConnect);
End;
InternetCloseHandle(hInternetOpen);
End;
End;


procedure TForm1.Button1Click(Sender: TObject);
var
s:string;
begin
// s:=PostInfo('www.delphibbs.com',80,
// '/delphibbs/index.asp','skin=2');
// s:=PostInfo('localhost/my.asp',80,'','');
//这样得到的是错误页面
s:=PostInfo('localhost',80,
'/my.asp','');
showmessage(s);
end;
end.
 
<input type="file" name="myfile" size="15" maxlength="100">
 
关注,请问测试成功了吗?能否给个例子?
 
不知如何测试,哪位老大解释一下
 
D6下有关于此控件的demo,看看吧!
 
http://www.vclxx.org/DELPHIGB/AAAT1028.HTM
WEBCOPY.ZIP

TWebCopy 是运用 HTTP 或 FTP 通讯协议从 Internet 彼端下载单一或多个文件的非可视构件,提供显示下载进度指示及取消下载的对话框 ( 1.1 版,无源码 Delphi 3.0/4.0/5.0 及 C++Builder 3.0/4.0 版适用 ),作者 : Bruno Fierens。

TURLIMAGE.ZIP

TURLImage 是能够透过 HTTP 通讯协议下载文件的非可视构件 ( 1.0 版,附源码 ),作者 : Bernhard Oker。

 
顶部