aspupload(最简单asp上传文件)
一、如何使用AspUpLoad上传图像的同时使用AspJpeg生成缩略图
这个肯定能符合你的要求,在客户端就可以实现。
<!DOCTYPE HTML PUBLIC"-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE> New Document</TITLE>
<META NAME="Generator" CONTENT="EditPlus">
<META NAME="Author" CONTENT="">
<META NAME="Keywords" CONTENT="">
<META NAME="Description" CONTENT="">
</HEAD>
<BODY>
<title>文件上传前台控制检测程序</title>
<style>
body,td{font-size:12px;}
</style>
<script language=javascript>
/*----------------------------------------
文件上传前台控制检测程序 v0.6
远程图片检测功能
检测上传文件类型
检测图片文件格式是否正确
检测图片文件大小
检测图片文件宽度
检测图片文件高度
图片预览
-----------------------------------------*/
var ImgObj=new Image();//建立一个图像对象
var AllImgExt=".jpg|.jpeg|.gif|.bmp|.png|"//全部图片格式类型
var FileObj,ImgFileSize,ImgWidth,ImgHeight,FileExt,ErrMsg,FileMsg,HasCheked,IsImg//全局变量图片相关属性
//以下为限制变量
var AllowExt=".jpg|.gif|.doc|.txt|"//允许上传的文件类型 0为无限制每个扩展名后边要加一个"|"小写字母表示
//var AllowExt=0
var AllowImgFileSize=70;//允许上传图片文件的大小 0为无限制单位:KB
var AllowImgWidth=500;//允许上传的图片的宽度 0为无限制单位:px(像素)
var AllowImgHeight=500;//允许上传的图片的高度 0为无限制单位:px(像素)
HasChecked=false;
function CheckProperty(obj)//检测图像属性
{
FileObj=obj;
if(ErrMsg!="")//检测是否为正确的图像文件返回出错信息并重置
{
ShowMsg(ErrMsg,false);
return false;//返回
}
if(ImgObj.readyState!="complete")//如果图像是未加载完成进行循环检测
{
setTimeout("CheckProperty(FileObj)",500);
return false;
}
ImgFileSize=Math.round(ImgObj.fileSize/1024*100)/100;//取得图片文件的大小
ImgWidth=ImgObj.width;//取得图片的宽度
ImgHeight=ImgObj.height;//取得图片的高度
FileMsg="\n图片大小:"+ImgWidth+"*"+ImgHeight+"px";
FileMsgFileMsg=FileMsg+"\n图片文件大小:"+ImgFileSize+"Kb";
FileMsgFileMsg=FileMsg+"\n图片文件扩展名:"+FileExt;
if(AllowImgWidth!=0&&AllowImgWidth<ImgWidth)
ErrMsgErrMsg=ErrMsg+"\n图片宽度超过限制。请上传宽度小于"+AllowImgWidth+"px的文件,当前图片宽度为"+ImgWidth+"px";
if(AllowImgHeight!=0&&AllowImgHeight<ImgHeight)
ErrMsgErrMsg=ErrMsg+"\n图片高度超过限制。请上传高度小于"+AllowImgHeight+"px的文件,当前图片高度为"+ImgHeight+"px";
if(AllowImgFileSize!=0&&AllowImgFileSize<ImgFileSize)
ErrMsgErrMsg=ErrMsg+"\n图片文件大小超过限制。请上传小于"+AllowImgFileSize+"KB的文件,当前文件大小为"+ImgFileSize+"KB";
if(ErrMsg!="")
ShowMsg(ErrMsg,false);
else
ShowMsg(FileMsg,true);
}
ImgObj.onerror=function(){ErrMsg='\n图片格式不正确或者图片已损坏!'}
function ShowMsg(msg,tf)//显示提示信息 tf=true显示文件信息 tf=false显示错误信息 msg-信息内容
{
msgmsg=msg.replace("\n","<li>");
msgmsg=msg.replace(/\n/gi,"<li>");
if(!tf)
{
document.all.UploadButton.disabled=true;
FileObj.outerHTML=FileObj.outerHTML;
MsgList.innerHTML=msg;
HasChecked=false;
}
else
{
document.all.UploadButton.disabled=false;
if(IsImg)
PreviewImg.innerHTML="<img src='"+ImgObj.src+"' width='60' height='60'>"
else
PreviewImg.innerHTML="非图片文件";
MsgList.innerHTML=msg;
HasChecked=true;
}
}
function CheckExt(obj)
{
ErrMsg="";
FileMsg="";
FileObj=obj;
IsImg=false;
HasChecked=false;
PreviewImg.innerHTML="预览区";
if(obj.value=="")return false;
MsgList.innerHTML="文件信息处理中...";
document.all.UploadButton.disabled=true;
FileExt=obj.value.substr(obj.value.lastIndexOf(".")).toLowerCase();
if(AllowExt!=0&&AllowExt.indexOf(FileExt+"|")==-1)//判断文件类型是否允许上传
{
ErrMsg="\n该文件类型不允许上传。请上传"+AllowExt+"类型的文件,当前文件类型为"+FileExt;
ShowMsg(ErrMsg,false);
return false;
}
if(AllImgExt.indexOf(FileExt+"|")!=-1)//如果图片文件,则进行图片信息处理
{
IsImg=true;
ImgObj.src=obj.value;
CheckProperty(obj);
return false;
}
else
{
FileMsg="\n文件扩展名:"+FileExt;
ShowMsg(FileMsg,true);
}
}
function SwitchUpType(tf)
{
if(tf)
str='<input type="file" name="file1" onchange="CheckExt(this)" style="width:180px;">'
else
str='<input type="text" name="file1" onblur="CheckExt(this)" style="width:180px;">'
document.all.file1.outerHTML=str;
document.all.UploadButton.disabled=true;
MsgList.innerHTML="";
}
</script>
<form enctype="multipart/form-data" method="POST" onsubmit="return HasChecked;">
<fieldset style="width: 372; height: 60;padding:2px;">
<legend><font color="#FF0000">图片来源</font></legend>
<input type="radio" name="radio1" checked onclick="SwitchUpType(true);">本地<input type="radio" name="radio1" onclick="SwitchUpType(false);">远程:
<input type="file" name="file1" onchange="CheckExt(this)" style="width:180px;">
<input type="submit" id="UploadButton" value="开始上传" disabled><br/>
<div style="border:1 solid#808080;background:#E0E0E0;width100%;height:20px;color:#606060;padding:5px;">
<table border="0"><tr><td width="60" id="PreviewImg">预览区</td><td id="MsgList" valign="top"></td></tr></table>
</div>
</fieldset>
</form>
</BODY>
</HTML>
二、如何使用AspUpload组件上传文件
你好,试试以下的方法:一、摘要Asp组件有内置的、服务器安装时附带的,更多的是第三方提供的,今天来学习文件上传的其中一个组件aspupload组件使用方法。
二、aspupload组件的下载、安装或注册 1、asp组件的下载、安装
(1)可以从网上下载。
(2)直接双击后进行安装。
AspUpload组件下载2、asp上传组件的功能
a.限制上载文件的大小
b.设置用户的权限
c.修改文件属性
d.同时上载多个文件
e.能够将文件保存到数据库中
f.支持文件删除,自动生成与服务器上文件不同名的文件
g.拥有管理权限的用户甚至可以使用该控件进行远程注册
三、aspupload组件的简单应用
1、实例一(1.asp):通过代码实现三个文件的上传功能。
如下图所示:
(1)静态页面:1个表单,三个文件域,一个按钮,其中表单form的动作如下。(2)其中客户端文件要注意几点:
*文件上载提交表单(Form)的enctype必须指定为“multipart/form-data”
*语句表示上载文件域,用户可以在该域中输入或选定文件。
*传递一个参数act(名称可自己取),其值可以自己随便定,目的是触发上传事件。
(3)动态代码如下:
2、实例二(2.asp):修改程序1.asp,要求在上传文件后显示上传文件的文件名及大小。
增加如下代码: response.write("文件1是:
")response.write(upload.files(1).path)
response.write("文件2是:
")response.write(upload.files(2).path)
response.write("文件3是:
")
response.write(upload.files(3).path)
说明:
upload.files方法用来获取文件的相关属性,path是文件的路径,size是文件的大小。
3、实例三(3.asp):修改程序2.asp,要求上传的三个文件大小不能超过5K,如果上传的文件已经存在则要求不覆盖文件。
在上传之前增加如下代码:
upload.setmaxsize 5120,false
upload.overwritefiles=fals说明:
(1)upload.setmaxsize 5120,false其功能为设置文件最大为5120字节,false参数说明当文件超过5120字节时则删除超过部分,true参数说明当文件超过5120字节时则出错。
(2)upload.overwritefiles=false,其功能表示文件不进行覆盖,如果上传同样文件名的文件,上传后文件名自动会在后面添加一个数字。
四、自学第二个上传文件的组件
1、Lyfupload组件的下载
2、学习此组件的安装或注册
3、通过课本例子进行文件的上传
五、问题
1、传到学校里服务器172.18.0.7运行时出现以下错误,Server.CreateObject失败
分析原因:学校服务器不支持aspupload上传组件
2、如果服务器不支持aspupload等上传组件,请大家使用无组件上传功能(编写代码),见书本上P322,此类代码比较复杂,同学们能够拿来使用,无须自己编写。
3、大家在网上申请个人空间时要看清服务器支持哪些组件,这样有利于编写代码。
三、上传的大文件
基于WEB的文件上传可以使用FTP和HTTP两种协议,用FTP的话虽然传输稳定,但安全性是个严重的问题,而且FTP服务器读用户库获取权限,这样对于用户使用来说还是不太方便。剩下只有HTTP。在HTTP中有3种方式,PUT、WEBDAV、RFC1867,前2种方法不适合大文件上传,基本上我们使用的web上传都是基于RFC1867标准的HTML中基于表单的文件上传。
RFC1867:
1.HTML表单
现有的HTML规范为INPUT元素的TYPE属性定义了八种可能的值,分别是:CHECKBOX, HIDDEN,MAGE,PASSWORD,RADIO,RESET,SUBMIT,TEXT。另外,当表单采用POST方式的时候,表单默认的具有“application/x-www-form-urlencoded”的ENCTYPE属性。
RFC1867标准对HTML做出了两处修改:
(1)为INPUT元素的TYPE属性增加了一个FILE选项。
(2)INPUT标记可以具有ACCEPT属性,该属性能够指定可被上传的文件类型或文件格式列表。
另外,本标准还定义了一种新的MIME类型:multipart/form-data,以及当处理一个带有ENCTYPE=multipart/form-data并且/或含有<INPUT type=file>的标记的表单时所应该采取的行为。
举例来说,当HTML表单作者想让用户能够上传一个或更多的文件时,他可以这么写:
<FORM ENCTYPE=multipart/form-data ACTION=_URL_ METHOD=POST>
File to process:
<INPUT NAME=userfile1 TYPE=file>
<INPUT TYPE=submit VALUE=Send File>
</FORM>
HTML DTD里所需要做出的改动是为InputType实体增加一个选项。此外,我们也建议用一系列用逗号分隔的文件类型来作为INPUT标记的ACCEPT属性。
...(其他元素)...
<!ENTITY% InputType(TEXT| PASSWORD| CHECKBOX|
RADIO| SUBMIT| RESET|
IMAGE| HIDDEN| FILE)>
<!ELEMENT INPUT- 0 EMPTY>
<!ATTLIST INPUT
TYPE%InputType TEXT
NAME CDATA#IMPLIED-- required for all but submit and reset
VALUE CDATA#IMPLIED
SRC%URI#IMPLIED-- for image inputs--
CHECKED(CHECKED)#IMPLIED
SIZE CDATA#IMPLIED--like NUMBERS,
but delimited with comma, not space
MAXLENGTH NUMBER#IMPLIED
ALIGN(top|middle|bottom)#IMPLIED
ACCEPT CDATA#IMPLIED--list of content types
>
...(其他元素)...
2.文件传输延迟
在某些情况下,在确实准备接受数据前,服务器先对表单数据中的某些元素(比如说用户名,账号等)进行验证是推荐的做法。但是,经过一定的考虑后,我们认为如果服务器想这样做的话,最好是采用一系列的表单,并将前面所验证过的数据元素作为“隐藏”字段传回给客户端,或者是通过安排表单使那些需要验证的元素先显示出来。这样的话,那些需要做复杂的应用的服务器可以自己维持事务处理的状态,而那些简单的应用的则可以实现得简单些。
HTTP协议可能需要知道整个事务处理中的内容总长度。即使没有明确要求,HTTP客户端也应该提供上传的所有文件的内容总长度,这样一个繁忙的服务器就能够判断文件的内容是否是过大以至于将不能完整地处理,从而返回一个错误代码并关闭该连接,而不用等到接受了所有的数据才进行判断。一些现有的CGI应用对所有的POST事务都需要知道内容总长度。
如果INPUT标记含有一个MAXLENGTH属性,客户端可以将这个属性值看作是服务器端所能够接受的传送文件的最大字节数。在这种情况下,服务器能够在上传开始前,提示客户端在服务器上有多少空间可以用来进行文件上传。但是应该引起注意的是,这仅仅是一个提示,在表单被创建后和文件上传前,服务器的实际需求可能会发生改变。
在任何情况下,如果接受的文件过大的话,任何一个HTTP服务器都有可能在文件传输的过程中中断传输。
3.传输二进制数据的其他解决办法
有些人曾经建议使用一种新的MIME类型aggregate,比如说aggregate/mixed或是content-transfer-encoding包来描述那些不确定长度的二进制数据,而不是靠分解为多个部分来表示。虽然我们并不反对这么做,但这需要增加额外的设计和标准化工作来让大家接受并理解aggregate。从另一方面来说,分解为多部分的机制工作得很好,能够非常简单的在客户发送端和服务器接受端加以实现,而且能像其他一些综合处理二进制数据的方式一样高效率地工作。
RFC上传
1.一次性得到上传的数据,然后分析处理。
看了N多代码之后发现,无组件程序和一些COM组件都是使用Request.BinaryRead方法。一次性得到上传的数据,然后分析处理。这就是为什么上传大文件很慢的原因了,IIS超时不说,就算几百M文件上去了,分析处理也得一阵子。
2.一边接收文件,一边写硬盘。
了解了一下国外的商业组件,比较流行的有Power-Web,AspUpload,ActiveFile,ABCUpload,aspSmartUpload,SA-FileUp。其中比较优秀的是ASPUPLOAD和SA-FILE,他们号称可以处理2G的文件(SA-FILE EE版甚至没有文件大小的限制),而且效率也是非常棒,难道编程语言的效率差这么多?查了一些资料,觉得他们都是直接操作文件流。这样就不受文件大小的制约。但老外的东西也不是绝对完美,ASPUPLOAD处理大文件后,内存占用情况惊人。1G左右都是稀松平常。至于SA-FILE虽然是好东西但是破解难寻。然后发现2款.NET上传组件,Lion.Web.UpLoadModule和AspnetUpload也是操作文件流。但是上传速度和CPU占用率都不如老外的商业组件。
做了个测试,LAN内传1G的文件。ASPUPLOAD上传速度平均是4.4M/s,CPU占用10-15,内存占用700M。SA-FILE也差不多这样。而AspnetUpload最快也只有1.5M/s,平均是700K/s,CPU占用15-39,测试环境: PIII800,256M内存,100M LAN。我想AspnetUpload速度慢是可能因为一边接收文件,一边写硬盘。资源占用低的代价就是降低传输速度。但也不得不佩服老外的程序,CPU占用如此之低.....。
上传问题
我们在上传大文件时都遇到过这样或那样的问题。设置很大的maxRequestLength值并不能完全解决问题,因为会block直到把整个文件载入内存后,再加以处理。实际上,如果文件很大的话,我们经常会见到Internet Explorer显示 The page cannot be displayed- Cannot find server or DNS Error,好像是怎么也catch不了这个错。为什么?因为这是个client side错误,server side端的Application_Error是处理不到的。
解决的方法是利用隐含的HttpWorkerRequest,用它的GetPreloadedEntityBody和 ReadEntityBody方法从IIS为建立的pipe里分块读取数据。Chris Hynes为我们提供了这样的一个方案(用HttpModule),该方案除了允许你上传大文件外,还能实时显示上传进度。
Lion.Web.UpLoadModule和AspnetUpload两个.NET组件都是利用的这个方案。
方案原理:
利用HttpHandler实现了类似于ISAPI Extention的功能,处理请求(Request)的信息和发送响应(Response)。
方案要点:
1. httpHandler or HttpModule
a.分块读取和写入数据
b.实时跟踪上传进度更新meta信息
2.利用隐含的HttpWorkerRequest用它的GetPreloadedEntityBody和 ReadEntityBody方法处理文件流
3.自定义Multipart MIME解析器。
自动截获MIME分割符。
将文件分块写如临时文件。
实时更新Appliaction状态(ReceivingData, Error, Complete)。