標題:用Delphi 6開發ASP上傳組件詳解
来源:互联网 发布:软件二次开发是什么 编辑:程序博客网 时间:2024/05/16 23:55
======================================================
注:本文源代码点此下载
======================================================
轉自:http://www.programfan.com
文檔中心:http://www.programfan.com/article/article.asp?classid=3
文件上传是web开发中经常要用到的功能,但asp本身和内置的组件都不支持文件上传功能。网上流
传的一些第三方组件虽然能够解决这个问题,但大多是要收费的,更别说open source了。本文将详细
剖析web文件上传的原理,以及一步步指导读者如何用delphi6开发一个asp上传组件。
源码和demo我已经发布在个人主页上
http://www.wushuang.net
1 html文件分析
首先我们来看一个html文件源码,文件名是test.htm,功能是提供用户上传的界面:
这个文件里包含了一个名为mainform的form,以及随手写的一些input域。注意这个form和一
般的form有两个不同的地方:一是它有一个type=file的域,没有value。用浏览器打开这个文件时,
这个域会表现为一个右侧有“浏览”字样的文件输入框,用户可以通过它来选择本地硬盘上的文件。二是
form有一个特殊的属性:enctype="multipart/form-data"。这个属性告诉浏览器要上传二进制文
件,并进行相应编码。
这种编码会产生什么样的表单信息呢?让我们来看看test.asp,也就是接受表单的asp文件的源码,
它非常简单:
如读者在注释中了解的,这段代码的功能是将表单的原始信息返回。让我们来看看它的运行效果。将
这两个文件置于web目录下,访问test.htm。在文件输入框中,选择一个文件(我选了一个jpg图片,
不过最大不要太大)。提交,然后可以看到这样一堆乱七八糟的信息:
-----------------------------7d2227629012e content-disposition: form-data;
name="mefile"; filename="c:\documents and settings\aaa\my documents\my
pictures\zzjh.jpg" content-type: image/pjpeg (作者注:以下为乱码)
-----------------------------7d2227629012e content-disposition: form-data;
name="a1" fdsaf -----------------------------7d2227629012e content-disposition:
form-data; name="a2" fdsaf -----------------------------7d2227629012e
content-disposition: form-data; name="a3" fdsaf
-----------------------------7d2227629012e content-disposition: form-data;
name="a4" fsdfsdsaf -----------------------------7d2227629012e
content-disposition: form-data; name="a5" 这个是这个
-----------------------------7d2227629012e content-disposition: form-data;
name="a6" fdsaf -----------------------------7d2227629012e content-disposition:
form-data; name="ok" ok -----------------------------7d2227629012e--
这就是用"multipart/form-data"方式编码的表单原始信息。其中那一段看起来是乱码的部分,就
是jpg图片的编码。
分析一下这段信息的格式:
-----------------------------7d2227629012e 这是各个域之间的分隔符。
content-disposition: form-data; 说明这是表单中的域。
name="mefile"; 域的名称。
filename="c:\documents and settings\aaa\my documents\my pictures\zzjh.jpg" 上
传文件在本地硬盘上的名称。
content-type: image/pjpeg 文件类型。
后面是文件本身的数据。
其它各个域的信息也可以以此类推。
众所周知,在asp中,使用request对象,可以访问用户提交表单的各个域。因为request对象
会对原始的表单信息进行解析,提取出表单中每个域的值。但是,request并不能解析这
"multipart/form-data"格式的表单信息。这就是asp不能直接支持文件上传的原因所在。读者可以
试试,在test.asp中,用request("mefile")这样的格式,是不能读取到正确的信息的。
问题的症结已经找到,解决的思路也很简单:用delphi开发一个com组件,接受这种原始表单信息,
将各个域一一提取出来,返回给asp文件。也就是完成request对象没有完成的功能。
2 用delphi开发组件
delphi6对开发asp组件提供了极好的支持,大大简化了我们的开发过程。
启动delphi 6,选择file-new-other-activex-activex library,这样就建立了一个
activex库。将此library改名为myobj,存盘。选择file-new-other-activex-active server
object,在coclassname中填入upfile,确定。这时会跳出一个标题为myobj.tlb的对话框,这是
delphi特有的以可视化方式编辑com接口的功能,用delphi开发过com的读者应该比较熟悉。
在myobj下的名为iupfile的interface下,添加5个属性和一个方法。如果不懂得如何操作,
请参见delphi参考书的相关部分。按f12可以看到生成的相应的myobj_tlb.pas文件,其中的
iupfile接口应该是这个样子:
iupfile = interface(idispatch)
['{5c40d0eb-5a22-4a1e-8808-62207ae04b51}']
procedure onstartpage(const ascriptingcontext: iunknown); safecall;
procedure onendpage; safecall;
functionget_form(formname: olevariant): olevariant; safecall;
functionget_filename: olevariant; safecall;
functionget_filesize: integer; safecall;
procedure filesaveas(filename: olevariant); safecall;
functionget_filedata: olevariant; safecall;
functionget_filetype: olevariant; safecall;
property form[formname: olevariant]: olevariant read get_form;
property filename: olevariant read get_filename;
property filesize: integer read get_filesize;
property filedata: olevariant read get_filedata;
property filetype: olevariant read get_filetype;
end;
其中的onstartpage方法和onendpage方法是delphi默认生成的,其它的是手动加入的。
切换到unit1.pas(也是delphi自动生成的),改名为upfile.pas存盘。可以看到存在一个
tupfile类的声明,它是继承自taspobject类和iupfile接口的。delphi 6已经自动生成了相应
的代码。接下来的任务就是实现这个接口。
除了完成iupfile接口中的属性和方法之后,还需要补充一些东西,以便完成我们的任务。最终的
tupfile类的声明如下:
tupfile = class(taspobject, iupfile)
public
protected
procedure onendpage; safecall;//页面开始
procedure onstartpage(const ascriptingcontext: iunknown); safecall;//页面
结束
procedure filesaveas(filename: olevariant); safecall;//保存文件
function get_form(formname: olevariant): olevariant; safecall;//
function get_filename: olevariant; safecall;
function get_filesize: integer; safecall;
function get_filedata: olevariant; safecall;
function get_filetype: olevariant; safecall;
private
fcontentdata:string;
ffiledata,ffilename,ffiletype:string;
fforminfo:tstringlist;
function instr(str1,str2:string;startpos:integer):integer;
procedure analyformdata(content:string);
end;
下面我们来一一分析这些成员的具体实现。
procedure tupfile.onstartpage(const ascriptingcontext: iunknown);
var
aolevariant : olevariant;
tmpvar : olevariant;
contentlength : integer;
i,delicount,pos1,pos2,lastpos : integer;
fdelimeter : string;
begin
inherited onstartpage(ascriptingcontext);
fforminfo := tstringlist.create;
contentlength := request.totalbytes;
aolevariant := contentlength;
tmpvar := request.binaryread(aolevariant);
for i := 1 to contentlength -1 do
begin
fcontentdata := fcontentdata + chr(byte(tmpvar[i]));
end;
pos1 := pos(#13#10,fcontentdata);
fdelimeter := copy(fcontentdata,1,pos1+1);
delicount := length(fdelimeter);
lastpos := 1;
pos1:=0;
while pos2>=pos1 do
begin
pos1 := instr(fdelimeter,fcontentdata,lastpos);
if pos1 = 0 then break;
pos1 := pos1 + delicount;
pos2 := instr(fdelimeter,fcontentdata,pos1)-1;
analyformdata(copy(fcontentdata,pos1,pos2-pos1-1));
lastpos := pos2;
end;
end;
前面说过,onstartpage方法是delphi自动生成的,在装载页面时发生。在这个方法中,我们完
成一些初始化的任务:读取表单的原始数据,解析表单中的域,并存入相应的属性中,以备调用。
由于delphi已经对asp中的对象进行了很好的封装,所以即使在delphi环境下,也可以方便地调
用它们,就象在asp中一样,例如request.totalbytes。首先将原始表单数据读入到一个
oleviarians类型的tmpvar中,然后通过一个循环,将它转换为delphi中的string格式,并存放
在fcontentdata中。
接下来,通过查找换行符,解析出分隔符的内容和长度。然后在一个循环中,用analyformdata成
员函数一一解析出每个域。初始化工作就这样完成了。
再看analyformdata函数的实现:
procedure tupfile.analyformdata(content: string);
var
pos1,pos2:integer;
formname,formvalue:string;
isfile:boolean;
begin
isfile := false;
pos1 := instr('name="',content,1)+6;
pos2 := instr('"',content,pos1);
formname := copy(content,pos1,pos2-pos1);
//检查是否文件
pos1 := instr('filename="',content,pos2+1);
if pos10 then
begin
pos2 := pos2 + 14;
ffiletype := copy(content,pos2,pos1-4-pos2);
end;
end
else
begin
fforminfo.add(formname+'='+formvalue);
end;
end;
如注释中所表达的,analyformdata提取原始数据中的域。如果是域是文件类型,则将文件类型和
文件数据分别放入ffiletype和ffiledata中。如果是其它类型,则将名称和值放入一个tstringlist
类型的fforminfo中。fforminfo中维护着除文件类型外的所有域的信息,以“名称=值”的格式存放。
function tupfile.get_form(formname: olevariant): olevariant;
begin
result := fforminfo.values[formname];
end;
这个函数返回域的值。只需要简单地调用fforminfo的values方法,就可以得到相应的值。这是
在tstringlist类内部实现的。
function tupfile.get_filename: olevariant;
begin
result := extractfilename(ffilename);
end;
function tupfile.get_filesize: integer;
begin
result := length(ffiledata);
end;
function tupfile.get_filedata: olevariant;
var
i:integer;
begin
result := vararraycreate( [0,length(ffiledata)], varbyte );
for i := 0 to length(ffiledata)-1 do
begin
result[i] := byte(ffiledata[i+1]);
end;
end;
这三个函数分别返回文件的名称、大小、数据。要注意的是,在返回文件数据时,必须进行相应的转
换,将delphi中的string类型转换为olevariant类型。
procedure tupfile.filesaveas(filename: olevariant);
var
fsout:tfilestream;
i:integer;
afile:file of byte;
begin
fsout := tfilestream.create(filename,fmcreate);
for i := 1 to length(ffiledata) do
begin
fsout.write(byte(ffiledata[i]),1)
end;
fsout.free;
end;
这个方法将文件保存到服务器上的磁盘。
编译myobj这个project,得到一个myobj.dll文件。开发工作就此完成。
3 使用asp上传组件
在命令行下,输入“regsvr32 myobj.dll”。弹出一个对话框,告诉你组件已经注册。如果找不到
regsvr32.exe这个文件,它在windows\system32或winnt\system32目录下。
将本文开头提到的test.asp文件修改为如下内容:
再次访问test.htm,提交表单。现在你可以看到相关的返回信息,并且在服务器上test.asp所处
的目录下找到上传的文件。
这个组件只能上传单个文件,但根据同样的原理,一次上传多个文件的功能也是不难实现的。有兴趣
的读者可以自行尝试。
申明
非源创博文中的内容均收集自网上,若有侵权之处,请及时联络,我会在第一时间内删除.再次说声抱歉!!!
博文欢迎转载,但请给出原文连接。
绿色通道:好文要顶关注我收藏该文与我联系
======================================================
在最后,我邀请大家参加新浪APP,就是新浪免费送大家的一个空间,支持PHP+MySql,免费二级域名,免费域名绑定 这个是我邀请的地址,您通过这个链接注册即为我的好友,并获赠云豆500个,价值5元哦!短网址是http://t.cn/SXOiLh我创建的小站每天访客已经达到2000+了,每天挂广告赚50+元哦,呵呵,饭钱不愁了,\(^o^)/
- 標題:用Delphi 6開發ASP上傳組件詳解
- 用Delphi 6开发ASP上传组件详解
- 用Delphi开发ASP分页组件
- 用delphi编写asp使用的组件
- 用Delphi编写ASP的ActiveX
- Delphi编写asp组件
- delphi 取asp数据
- 用Delphi开发报表打印的ASP组件
- 用DELPHI为ASP开发文件上载组件
- 用DELPHI为ASP开发文件上载组件
- 用DELPHI为ASP开发文件上载组件
- 一个用delphi开发asp组件的例子
- 用 Delphi 7 创建 ActiveX 组件交 ASP 使用
- 用Delphi开发用于ASP的OLE Automation Server
- 用 Delphi 7 创建 ActiveX 组件交 ASP 使用
- 用Delphi编写ASP的ActiveX服务器组件的问题
- 用DELPHI为ASP开发文件上载组件
- 用Delphi为Asp开发文件上载组件的原理和具体实现过程
- 初试java ant
- jQuery Ajax 实例 全解析
- 高性能Javascript HTML集合访问的学习笔记
- ajax跨域访问代理文件下载(asp、php、asp.net)
- (转)智能指针的另外一种实现 - Smart pointers in Delphi
- 標題:用Delphi 6開發ASP上傳組件詳解
- java7新特性(1)
- ASP.NET AJAX Extensions 学习笔记之下载安装
- Ajax杂谈
- IPSEC流程例子及两个阶段的协商过程详细介绍
- 请问你看完这个有何感想?关于Delphi中的类型转换??
- HTML-加速、再加速
- HTML DOM Event 对象
- 微软出的AJAX控件的安装(转载)