鲜香菇瘦肉粥的做法:delphi中通过http控件上载文件的问题(紧急)

来源:百度文库 编辑:偶看新闻 时间:2024/05/04 07:37:17

delphi中通过http控件上载文件的问题(紧急)[问题点数:100分,结帖人:linuxchen]

  • linuxchen
  • (chen)
  • 等 级:
  • 结帖率:
楼主发表于:2003-06-03 15:16:32
http控件能不能实现post文件?
要求效果就像普通的html中通过表单(form中 ))发送文件一样.

我试过用post字符串好像没问题。。但是要实现这种方式没头绪
  • 对我有用[0]
  • 丢个板砖[0]
  • 引用
  • 举报
  • 管理
  • TOP
回复次数:14
  • whitetiger8
  • (键盘未敲坏,基本功未练成)
  • 等 级:
#1楼 得分:0回复于:2003-06-03 15:23:28关注。。
  • 对我有用[0]
  • 丢个板砖[0]
  • 引用
  • 举报
  • 管理
  • TOP
精华推荐:想做一个所见即所得的html编辑器 谁有这方面技术资料 谢谢了
  • linuxchen
  • (chen)
  • 等 级:
#2楼 得分:0回复于:2003-06-03 15:47:35换一种说法就是用delphi的http控件提交包含文件的表单。。服务器端用普通的文件上载控件
像接受html页面中的form提交一样来接受上载的文件。
  • 对我有用[0]
  • 丢个板砖[0]
  • 引用
  • 举报
  • 管理
  • TOP
精华推荐:这样算不算线程死锁状态
  • yk1028
  • 等 级:
#3楼 得分:100回复于:2003-06-03 16:33:51http://www.matlus.com/scripts/website.dll/Tutorials?DelphiTCPIP&IndyMultiPartFormData&5

gz!!!
把上面的研究一下,hehe.
  • 对我有用[0]
  • 丢个板砖[0]
  • 引用
  • 举报
  • 管理
  • TOP
精华推荐:从SQL Server 读取图片
  • linuxchen
  • (chen)
  • 等 级:
#4楼 得分:0回复于:2003-06-04 11:52:20非常感谢yk1028
已经解决。。等会有时间总结一下
  • 对我有用[0]
  • 丢个板砖[0]
  • 引用
  • 举报
  • 管理
  • TOP
精华推荐:年终总结(一):DirectShow做的播放器(有部分代码)
  • yk1028
  • 等 级:
#5楼 得分:0回复于:2003-06-04 12:14:20也是昨天偶然查到的.
俺还没摆平   :(  
这是delphi7环境
总结了帖出来吧,我搜索一下很多人要这方面的
  • 对我有用[0]
  • 丢个板砖[0]
  • 引用
  • 举报
  • 管理
  • TOP
精华推荐:申请delphi区大版
  • nydelphi
  • (程序狂人)
  • 等 级:
#6楼 得分:0回复于:2003-06-04 12:34:00D
  • 对我有用[0]
  • 丢个板砖[0]
  • 引用
  • 举报
  • 管理
  • TOP
  • linuxchen
  • (chen)
  • 等 级:
#7楼 得分:0回复于:2003-06-12 13:27:16对不起,很长时间没回贴也没结贴
其实很简单:
就是利用idhttp.post
post方法有三个参数
1。调用的脚本
2。post的stream
3。接收返回信息的stream
问题的关键就是构造符合规范的stream格式(要跟从网页的form中post的一模一样)
具体的格式看看带的MsMultiPartFormData.pas
其实可以用例子中带的MsMultiPartFormData.pas,它里面已经封装的很好了。


  • 对我有用[0]
  • 丢个板砖[0]
  • 引用
  • 举报
  • 管理
  • TOP
  • linuxchen
  • (chen)
  • 等 级:
#8楼 得分:0回复于:2003-06-12 13:31:25我的email:   linux_chen@263.net  
如果需要我把我这边的例子发给你
  • 对我有用[0]
  • 丢个板砖[0]
  • 引用
  • 举报
  • 管理
  • TOP
  • zhanghuip
  • (大男孩)
  • 等 级:
#9楼 得分:0回复于:2003-06-12 14:50:56能给我也发一个吗,谢谢
zhanghuip@163.com
  • 对我有用[0]
  • 丢个板砖[0]
  • 引用
  • 举报
  • 管理
  • TOP
  • linuxchen
  • (chen)
  • 等 级:
#10楼 得分:0回复于:2003-06-13 14:53:12
例子里面带的例子indy版本要求比较新,好像多了一些属性方法
在新版本的indy里面已经封装了这种应用,有一个unit叫IdMultipartFormData.pas
装新版本indy时,必须把老的indy文件完全删除干净,不然装起来老报错。

我在csdn里说的是用MsMultiPartFormData.pas(它实现发送格式化的请求stream)

你可以直接包含该单元就可以了,这个只用到indy的post方法,应该delphi自带的indy就可以用了

网上下载的那个例子indy版本较高。我改了一下,在附件里,你现在应该可以用了

看完这个应该能解决你的问题,我的问题跟你一样。
  • 对我有用[0]
  • 丢个板砖[0]
  • 引用
  • 举报
  • 管理
  • TOP
  • yk1028
  • 等 级:
#11楼 得分:0回复于:2003-06-13 15:15:18收到
thanks
  • 对我有用[0]
  • 丢个板砖[0]
  • 引用
  • 举报
  • 管理
  • TOP
  • wood_ke
  • (天煞孤星)
  • 等 级:
#12楼 得分:0回复于:2003-06-13 16:31:55能给我一个吗??
我找了好久!!!谢谢!!
wood_ke@163.net
  • 对我有用[0]
  • 丢个板砖[0]
  • 引用
  • 举报
  • 管理
  • TOP
  • linuxchen
  • (chen)
  • 等 级:
#13楼 得分:0回复于:2003-06-16 16:56:52附带的例子由于indy版本的问题,有点小问题(其实用文本工具修改一下dfm,去掉新增的属性就可以了)。我干脆把源码给贴出来吧,版权属于原作者

一.用于实现form流格式的单元(MsMultiPartFormData.pas)
unit   MsMultiPartFormData;

interface

uses
    SysUtils,   Classes;

const
    CONTENT_TYPE   =   'multipart/form-data;   boundary= ';
    CRLF   =   #13#10;
    CONTENT_DISPOSITION   =   'Content-Disposition:   form-data;   name= "%s " ';
    FILE_NAME_PLACE_HOLDER   =   ';   filename= "%s " ';
    CONTENT_TYPE_PLACE_HOLDER   =   'Content-Type:   %s '   +   crlf   +   crlf;
    CONTENT_LENGTH   =   'Content-Length:   %d '   +   crlf;

type
    TMsMultiPartFormDataStream   =   class(TMemoryStream)
    private
        FBoundary:   string;
        FRequestContentType:   string;
        function   GenerateUniqueBoundary:   string;
    public
        procedure   AddFormField(const   FieldName,   FieldValue:   string);
        procedure   AddFile(const   FieldName,   FileName,   ContentType:   string;   FileData:   TStream);   overload;
        procedure   AddFile(const   FieldName,   FileName,   ContentType:   string);   overload;
        procedure   PrepareStreamForDispatch;
        constructor   Create;
        property   Boundary:   string   read   FBoundary;
        property   RequestContentType:   string   read   FRequestContentType;
    end;

implementation

{   TMsMultiPartFormDataStream   }

constructor   TMsMultiPartFormDataStream.Create;
begin
    inherited;
    FBoundary   :=   GenerateUniqueBoundary;
    FRequestContentType   :=   CONTENT_TYPE   +   FBoundary;
end;

procedure   TMsMultiPartFormDataStream.AddFile(const   FieldName,   FileName,
    ContentType:   string;   FileData:   TStream);
var
    sFormFieldInfo:   string;
    Buffer:   PChar;
    iSize:   Int64;
begin
    iSize   :=   FileData.Size;
    sFormFieldInfo   :=   Format(CRLF   +   '-- '   +   Boundary   +   CRLF   +   CONTENT_DISPOSITION   +
        FILE_NAME_PLACE_HOLDER   +   CRLF   +   CONTENT_LENGTH   +
            CONTENT_TYPE_PLACE_HOLDER,   [FieldName,   FileName,   iSize,   ContentType]);

    Write(Pointer(sFormFieldInfo)^,   Length(sFormFieldInfo));
    FileData.Position   :=   0;
    GetMem(Buffer,   iSize);
    try
        FileData.Read(Buffer^,   iSize);
        Write(Buffer^,   iSize);
    finally
        FreeMem(Buffer,   iSize);
    end;
end;

procedure   TMsMultiPartFormDataStream.AddFile(const   FieldName,   FileName,
    ContentType:   string);
var
    FileStream:   TFileStream;
begin
    FileStream   :=   TFileStream.Create(FileName,   fmOpenRead   or   fmShareDenyWrite);
    try
        AddFile(FieldName,   FileName,   ContentType,   FileStream);
    finally
        FileStream.Free;
    end;
end;

procedure   TMsMultiPartFormDataStream.AddFormField(const   FieldName,
    FieldValue:   string);
var
    sFormFieldInfo:   string;
begin
    sFormFieldInfo   :=   Format(CRLF   +   '-- '   +   Boundary   +   CRLF   +   CONTENT_DISPOSITION   +   CRLF   +   CRLF   +
        FieldValue,   [FieldName]);
    Write(Pointer(sFormFieldInfo)^,   Length(sFormFieldInfo));
end;

function   TMsMultiPartFormDataStream.GenerateUniqueBoundary:   string;
begin
    Result   :=   '--------------------------- '   +   FormatDateTime( 'mmddyyhhnnsszzz ',   Now);
end;

procedure   TMsMultiPartFormDataStream.PrepareStreamForDispatch;
var
    sFormFieldInfo:   string;
begin
    sFormFieldInfo   :=   CRLF   +   '-- '   +   Boundary   +   '-- '   +   CRLF;
    Write(Pointer(sFormFieldInfo)^,   Length(sFormFieldInfo));
    Position   :=   0;
end;
end.

二。调用的方法:
    1。先包含MsMultiPartFormData(uses   MsMultiPartFormData;)
    2。把如下代码加到需要的地方
var
    ResponseStream:   TMemoryStream;
    MultiPartFormDataStream:   TMsMultiPartFormDataStream;
begin
    MultiPartFormDataStream   :=   TMsMultiPartFormDataStream.Create;
    ResponseStream   :=   TMemoryStream.Create;
    try
        IdHttp1.Request.ContentType   :=   MultiPartFormDataStream.RequestContentType;
//添加表单的字段   (前一个参数是字段名,后一个参数是字段值)
        MultiPartFormDataStream.AddFormField( 'PersonName ',   edtPersonName.Text);
        MultiPartFormDataStream.AddFormField( 'Description ',   edtDescription.Text);
//添加上载的文件(第一个是字段名,第二个是文件名,第三个是文件类型)
        MultiPartFormDataStream.AddFile(edtFile.Name,   edtFile.Text,   edtMIMEType.Text);
        {   You   must   make   sure   you   call   this   method   *before*   sending   the   stream   }
        MultiPartFormDataStream.PrepareStreamForDispatch;
        MultiPartFormDataStream.Position   :=   0;
//调用idhttp的post方法,第一个参数是用于处理上载form的asp/php等等脚本,第三个是接收脚本执行完成后的返回内容)
        IdHTTP1.Post( "http://xxx.xxx.com/upload.asp ",   MultiPartFormDataStream,   ResponseStream);
    finally
        MultiPartFormDataStream.Free;
        ResponseStream.Free;
    end;
end;


从这些代码可以引出很多应用:
1。asp里调用其它脚本语言如(php,jsp,等等)。把这段代码用组件实现,在asp中调用,就可以     了。
2。从普通的应用程序调用asp,php等等脚本
3。传统的html中,必须在浏览器中选择文件,才能上载(号称是为了安全),通过这个就可以实现
不通过选择文件,实现上载。

  • 对我有用[1]
  • 丢个板砖[0]
  • 引用
  • 举报
  • 管理
  • TOP
  • wood_ke
  • (天煞孤星)
  • 等 级:
#14楼 得分:0回复于:2003-06-18 15:15:36hao