无组件图片与文本同步存入数据库的最简单的办法,asp无组件上传的原理
分类:多线程

    用ASP编写网站应用程序时间长了,难免会遇到各式各样的问题,其中关于如何上传文件到服务器恐怕是遇见最多的问题了,尤其是上传图片,比如你想要在自己的社区里面实现类似网易虚拟社区提供的“每日一星”的功能,就要提供给网友上传照片的功能。上传图片文件到服务器可以使用各种免费的文件上传组件,使用起来功能虽然很强大,但是由于很多情况下,我们只能使用免费的支持ASP的空间或者租用别人的虚拟空间,对于第一种情况,我们根本就没有可能来使用文件上传组件;至于第二种情况,我们也要付出不少的“银子”才可以。除非你拥有自己的虚拟主机,你就可以随便的在服务器上面安装自己所需要的组件,这种情况对于大多数人来说是可望而不可及的。那我们就没有办法了吗?呵呵,答案是肯定的(当然是肯定的了,要不然我也没法写出这篇文章啊)。下面就让我们一起来使用纯ASP代码来实现图片的上传以及保存到数据库的功能(顺便也实现显示数据库中的图片到网页上的功能)。 
    首先我们先来熟悉一下将要使用的对象方法。我们用来获取上一个页面传递过来的数据一般是使用Request对象。同样的,我们也可以使用Request对象来获取上传上来的文件数据,使用的方法是Request.BinaryRead()。而我们要从数据库中读出来图片的数据显示到网页上面要用到的方法是: 
    Request.BinaryWrite()。在我们得到了图片的数据,要保存到数据库中的时候,不可以直接使用Insert语句对数据库进行操作,而是要使用ADO的AppendChunk方法,同样的,读出数据库中的图片数据,要使用GetChunk方法。各个方法的具体语法如下:* Request.BinaryRead语法: 
    variant = Request.BinaryRead(count) 
    参数 variant 返回值保存着从客户端读取到数据。 
    count 指明要从客户端读取的数据量大小,这个值小于或者等于使用方法 
    Request.TotalBytes得到的数据量。
 
    * Request.BinaryWrite语法: 
    Request.BinaryWrite data
    参数 data 要写入到客户端浏览器中的数据包。
 
    * Request.TotalBytes语法: 
    variant = Request.TotalBytes 
    参数 variant 返回从客户端读取到数据量的字节数。
 
    * AppendChunk语法 
    将数据追加到大型文本、二进制数据 Field 或 Parameter 对象。 
    object.AppendChunk Data 
    参数 object Field 或 Parameter 对象 
    Data 变体型,包含追加到对象中的数据。 
    
    说明 
    使用 Field 或 Parameter 对象的 AppendChunk 方法可将长二进制或字符数据填写到对象中。在系统内存有限的情况下,可以使用 AppendChunk 方法对长整型值进行部分而非全部的操作。 

一:前言

文章来源:宝玉BLOG    

使用ASP制作网站计数器,一般采用ASP的内置对象application,用一文本文件来保存记数值,在这里我将介绍另外一种方法,采用数据库来制作,而且是多用户版的,这样,不仅可以自己使用,而且可以为其它网站服务了。下面是具体做法: 

   * GetChunk语法 
   返回大型文本或二进制数据 Field 对象的全部或部分内容 。 
   variable = field.GetChunk( Size ) 
   返回值返回变体型。 
   参数Size 长整型表达式,等于所要检索的字节或字符数。 
   说明 使用 Field 对象的 GetChunk 方法检索其部分或全部长二进制或字符数据。在系统内存有限的情况下,可使用 GetChunk 方法处理部分而非全部的长整型值。GetChunk 调用返回的数据将赋给“变量”。如果 Size 大于剩余的数据,则GetChunk 仅返回剩余的数据而无需用空白填充“变量”。如果字段为空,则GetChunk 方法返回 Null。每个后续的GetChunk 调用将检索从前一次 GetChunk 调用停止处开始的数据。但是,如果从一个字段检索数据然后在当前记录中设置或读取另一个字段的值,ADO 将认为已从第一个字段中检索出数据。如果在第一个字段上再次调用 GetChunk 方法,ADO 将把调用解释为新的GetChunk 操作并从记录的起始处开始读取。如果其他 Recordset 对象不是首个Recordset 对象的副本,则访问其中的字段不会破坏 GetChunk 操作。如果 Field 对象的Attributes 属性中的 adFldLong 位设置为 True,则可以对该字段使用 GetChunk 方法.。如果在 Field 对象上使用 Getchunk 方法时没有当前记录,将产生错误 3021(无当前记录)。接下来,我们就要来设计我们的数据库了,作为测试我们的数据库结构如下(Access97): 

首先,没有料到图片与文本的上传会引起这么大的注意。上一篇贴子(Id=435906)贴出后,有不少人来信说看不懂。或是仍然不能实现。我就以一种完全简单的手法。完成无组件的文本与图片上传数据库所有过程。希望能帮助所有对此有疑问的网友。

一、无组件上传的原理
我还是一点一点用一个实例来说明的吧,客户端HTML如下。要浏览上传附件,我们通过<input type="file">元素,但是一定要注意必须设置form的enctype属性为"multipart/form-data":

● 制作前的准备 
  由于要使用数据库来保存记数值与用户信息,所以必须先建立数据库(这里我们采用ACCESS格式),可以用Microsoft Access建立下面的数据库: 

字段名称    类型    描述 

二:准备工作

<form method="post" action="upload.asp" enctype="multipart/form-data">
<label>
<input type="file" name="file1" />
</label>
<br />
<input type="text" name="filename" value="default filename"/>
<br />
<input type="submit" value="Submit"/>
<input type="reset" value="Reset"/>
</form>

数据库名称为:count.mdb 

  id    自动编号   主键值 

按照惯例,我先将我的测试环境告诉大家。
系统:Win98se + pws + asp 
编程环境:Visual Interdev 6.0 
数据库:Access2000 (因为网友问的最多的都是Access2000的问题。)
建一个库:access2000中,先建好一个Test.mdb的数据库。具体有四个字段。
id | text1 | text2 | img
自动编号 文本 文本 OLE对象 ’如果是sql server 则选择(image即可)

在后台asp程序中,以前获取表单提交的ASCII 数据,非常的容易。但是如果需要获取上传的文件,就必须使用Request对象的BinaryRead方法来读取。BinaryRead方法是对当前输入流进行指定字节数的二进制读取,有点需要注意的是,一旦使用BinaryRead 方法后,再也不能使用Request.Form 或 Request.QueryString 集合了。结合Request对象的TotalBytes属性,可以将所有表单提交的数据全部变成二进制,不过这些数据都是经过编码的。首先让我们来看看这些数据是如何编码的,有无什么规律可循,编段代码,在代码中我们将BinaryRead读取的二进制转化为文本,输出出来,在后台的upload.asp中(注意该示例不要上传大文件,否则可能会造成浏览器死掉):
<%
Dim biData, PostData
Size = Request.TotalBytes
biData = Request.BinaryRead(Size)
PostData = BinaryToString(biData,Size)
Response.Write "<pre>" & PostData & "</pre>" 使用pre,原样输出格式
借助RecordSet将二进制流转化成文本
Function BinaryToString(biData,Size)
Const adLongVarChar = 201
Set RS = createObject("ADODB.Recordset")
RS.Fields.Append "mBinary", adLongVarChar, Size
RS.Open
RS.AddNew
RS("mBinary").AppendChunk(biData)
RS.update
BinaryToString = RS("mBinary").Value
RS.Close
End Function
%>

表名为:counttable 

img OLE对象   用来保存图片数据  

三:Are you ready ,Go!!!

简单起见,上传一个最简单的文本文件(G:homepage.txt,内容为"宝玉: filename",提交看看输出结果:

有下面字段: 

对于在MS SQL Server7中,对应的结构如下: 

3-1.建上传表单:
    我们知道,图像与文本是两种不同制式的文件(二进制,流式文本)而如果要同一表单提交的话,(file格式提交)则我们获取时就不能用原来的方法request.form而必须用request.TotalBytes来获得所有的提交资料。但这时两种格式的文件混合在一起比较难分。我的上一贴已经告诉大家用二进制的方法来分开这些资料。但十分麻烦,要用到许多二进值的函数,所以许多网友来信问我有没有更简单的方法,好。我可以告诉大家,有!而且保证下面
的方法保证一学就会。(这种方法很另类但伟人说过白猫,黑猫。能上网的就是好猫!)

-----------------------------7d429871607fe
Content-Disposition: form-data; name="file1"; filename="G:homepage.txt"
Content-Type: text/plain
宝玉:
-----------------------------7d429871607fe
Content-Disposition: form-data; name="filename"
default filename
-----------------------------7d429871607fe--
可以看出来对于表单中的项目,是用过"-----------------------------7d429871607fe"这样的边界来分隔成一块一块的,每一块的开始都有一些描述信息,例如:Content-Disposition: form-data; name="filename",在描述信息中,通过name="filename"可以知道表单项的name。如果有filename="G:homepage.txt"这样的内容,说明是一个上传的文件,如果是一个上传的文件,那么描述信息会多一行Content-Type: text/plain来描述文件的Content-Type。描述信息和主体信息之间是通过换行来分隔的。

user:[数据类型:文本,字段大小:255]保存用户名 

字段名称    类型    描述 

upload.asp(具体代码如下)

嗯,基本上清晰了,根据这个规律我们就知道该怎么来分离数据,再对分离的数据进行处理了,不过差点忽略一个问题,就是边界值(上例中的"-----------------------------7d429871607fe")是怎么知道的?每次上传这个边界值是不一样的,还好还好asp中可以通过Request.ServerVariables( "HTTP_CONTENT_TYPE")来获之,例如上例中HTTP_CONTENT_TYPE内容为:"multipart/form-data; boundary=---------------------------7d429871607fe",有了这个,我们不仅可以判断客户端的form中有无使用enctype="multipart/form-data"(如果没有使用,那么下面就没必要执行啦),还可以获取边界值boundary=---------------------------7d429871607fe。(注意:这里获取的边界值比上面的边界值开头要少"--",最好补充上。)

pageurl:[数据类型:文本,字段大小:255]保存用户主页地址 

  id     int(Identity) 主键值 

<% @ language=vbscript %>
<html>
<head>
<meta name="VI60_defaultClientScript" content="VBScript">
<title> File Upload </title>
<script ID="clientEventHandlersVBS" LANGUAGE="vbscript">
<!-- 
Sub form2_onsubmit //** 这里是关键,当form2在提交的过程中时,即活form1的提交
form1.submit //**所以我们这里用了两个表单,但只用一个提交就可以了。
End Sub
-->
</script>
</head>
<body>

至于如何分析数据的过程我就不多赘述了,无非就是借助InStr,Mid等这样的函数来分离出来我们想要的数据。

curvalue:[数据类型:数字,字段大小:长整型]保存计数器值 

img   image     用来保存图片数据  

<form name="form1" ENCTYPE="multipart/form-data" ACTION="upimage.asp" 
METHOD="POST" target="_blank">
Please choose a picture to upload: <br>
<input NAME="picture" TYPE="FILE"> <br>
</form>

二、分块上传,记录进度
要实时反映进度条,实质就是要实时知道当前服务器获取了多少数据?再回想一下我们实现上传的过程,我们是通过Request.BinaryRead(Request.TotalBytes)来实现的,在Request的过程中我们无法得知当前服务器获取了多少数据。所以只能通过变通的方法了,如果我们可以将获取的数据分成一块一块的,然后根据已经上传的块数我们就可以算出来当前上传了多大了!也就是说,如果我1K为1块,那么上传1MB的输入流就分成1024块来获取,例如我当前已经获取了100块,那么就表明当前上传了100K。当我提出分块的时候很多人觉得不可思议,因为他们都忽略BinaryRead方法不仅是可以读取指定大小,而且可以连续读取的。

  同时需准备十个图片:0-9,放于目录"1"中,文件名为0.gif,1.gif......(用来图形化显示的计数值) 

现在开始正式编写我们的纯ASP代码上传部分了,首先,我们有一个提 

<form name="form2" action="uptext.asp" method="post">
<input type="text" name="text1"><br>
<input type="text" name="text2"><br>
<input type="submit" value="提交">
</form>

写个例子来验证一下分块读取的完整性,在刚才的例子基础上(注意该示例不要上传大文件,否则可能会造成浏览器死掉):

● 用户申请表单制作 
  可以使用Microsoft FrontPage制作下面的计数器申请表单,文件名保存为:get.htm 

供给用户的上传界面,可以让用户选择要上传的图片。代码如下 

</body>
</html>

<%
Dim biData, PostData, TotalBytes, ChunkBytes
ChunkBytes = 1 * 1024 分块大小为1K
TotalBytes = Request.TotalBytes 总大小
PostData = "" 转化为文本类型后的数据
ReadedBytes = 0 初始化为0
分块读取
Do While ReadedBytes < TotalBytes
biData = Request.BinaryRead(ChunkBytes) 当前块
PostData = PostData & BinaryToString(biData,ChunkBytes) 将当前块转化为文本并拼接
ReadedBytes = ReadedBytes + ChunkBytes 记录已读大小
If ReadedBytes > TotalBytes Then ReadedBytes = TotalBytes
Loop
Response.Write "<pre>" & PostData & "</pre>" 使用pre,原样输出格式
将二进制流转化成文本
Function BinaryToString(biData,Size)
Const adLongVarChar = 201
Set RS = createObject("ADODB.Recordset")
RS.Fields.Append "mBinary", adLongVarChar, Size
RS.Open
RS.AddNew
RS("mBinary").AppendChunk(biData)
RS.update
BinaryToString = RS("mBinary").Value
RS.Close
End Function
%>

<form method="POST" action="getcl.asp"> 
<p>用 户 名<input type="text" name="user" size="20"></p> 
<p>计数器值<input type="text" name="curvalue" size="20"></p> 
<p>主页地址<input type="text" name="pageurl" size="20"></p> 
<p><input type="submit" value="提交" name="B1"><input type="reset" value="全部重写" name="B2"></p> 
</form> 

(upload.htm): 

3-2 兵分两路来处理数据。
首先,文本很简单。

试验一下上传刚才的文本文件,输出结果证明这样分块读取的内容是完整的,并且在While循环中,我们可以在每次循环时将当前状态记录到Application中,然后我们就可以通过访问该Application动态获取上传进度条。

  表单中的action="getcl.asp"表示用getcl.asp文件来处理用户的输入,那么,getcl.asp文件怎么处理用户的输入,将用户的输入加入数据库呢?方法如下: 

<html> 

uptext.asp (代码如下)

另:上例中是通过字符串拼接的,如果是要拼接二进制数据,可以通过ADODB.Stream对象的Write方法,示例代码如下:

<%'建立与数据库的连接 
Set conn = Server.CreateObject("ADODB.Connection") 
dbpath=server.MapPath("count.mdb")'取得数据库的实际路径 
conn.open "driver={Microsoft Access Driver (*.mdb)};dbq="&DbPath 
set rs=server.CreateObject("adodb.recordset") 

<body> 

<% @ language=vbscript %>
<%
strconn="driver={microsoft access driver (*.mdb)};dbq="&server.MapPath
("test.mdb")

Set bSourceData = createobject("ADODB.Stream")
bSourceData.Open
bSourceData.Type = 1 Binary
Do While ReadedBytes < TotalBytes
biData = Request.BinaryRead(ChunkBytes)
bSourceData.Write biData 直接使用write方法将当前文件流写入bSourceData中
ReadedBytes = ReadedBytes + ChunkBytes
If ReadedBytes > TotalBytes Then ReadedBytes = TotalBytes
Application("ReadedBytes") = ReadedBytes
Loop

'取得用户信息 
user=Request.Form("user") 
pageurl=Request.Form("pageurl") 
curvalue=Request.Form("curvalue") 

<center> 

text1=request.form("text1")
text2=request.form("text2")
response.write text1
response.write text2

三、保存上传的文件
通过Request.BinaryRead获取提交数据,分离出上传文件后,根据数据类型的不同,保存方式也不同:

'先检查用户名是否存在 
sql="select * from counttable where user='"&user&"'" 
rs.Open sql,conn,1,3 
if not rs.EOF then 
Response.Write"<title>申请出错</title>" 
Response.Write"对不起,用户名已经存在!</title>" 

   <form name="mainForm" enctype="multipart/form-data" 

set rs=Server.CreateObject("adodb.recordset")
sql="SELECT top 1 * FROM imgtable ORDER BY id DESC" ’这里的意思是选择最后一个Id,既刚刚被改动
rs.Open sql,strconn,1,3 ’就是你上传的图像的两个文本字段。

对于二进制数据,可以直接通过ADODB.Stream对象的SaveToFile方法,将二进制流保存成为文件。
对于文本数据,可以通过TextStream对象的Write方法,将文本数据保存到文件中。
对于文本数据和二进制数据,是可以方便的相互转换的,对于上传小文件来说,两者基本上没什么差别。但是两种方式保存时还是有一些差别的,对于ADODB.Stream对象,必须将所有数据全部装载完才可以保存成文件,所以使用这种方式如果上传大文件将很占用内存,而对于TextStream对象,可以在文件创建好后,一次Write一部分,分多次Write,这样的好处是不会占用服务器内存空间,结合上面分析的分块获取数据原理,我们可以每获取一块上传数据就将之Write到文件中。我曾做过试验,同样本机上传一个200多MB的文件,使用第一种方式内存一直在涨,到最后直接提示计算机虚拟内存不足,最可恨是即使进度条表示文件已经上传完,但是最终文件还是没有保存上。而使用后一种方法,上传过程中内存基本上无什么变化。

'结束向下处理,要求用户重填 
Response.End 
end if 

action="process.asp" method=post> 

rs("text1")=text1 ’注意,这里是改动不是添加,所以不用addnew。
rs("text2")=text2
rs.Update
rs.Close
%>
接着,来处理图像。
upimage.asp (具体代码如下)

四、未解决的难题
我在博客园上看到Bestcomy描述他的Asp.Net上传组件是可以和Sever.SetTimeOut无关的,而在Asp中我是没能做到,对于上传大文件,就只有将Server.SetTimeOut设置为一个很大的值才可以。不知道有没有比较好的解决方法。

'将用户信息加入数据库 
rs.AddNew 
rs("user")=user 
rs("pageurl")=pageurl 
rs("curvalue")=curvalue 
rs.Update 
rs.Close 
set rs=nothing 
conn.Close 
set conn=nothing 
%> 

    <input type=file name=mefile><br> 

<%
FormSize = Request.TotalBytes ’得到数据
FormData = Request.BinaryRead( FormSize )

如果我们在保存文件时,使用TextStream对象的Write方法,那么如果用户上传时中断了文件传输,已经上传的那部分文件还是在的,如果可以断点续传就好了。关键问题是Request.BinaryRead方法虽然可以分块读取,但是却不能跳过某一段读取!

● 计数程序制作 
  完成了用户申请处理的制作,下面就要制作计数器的核心程序(count.asp)了。具体方法如下: 
<% 
Set conn = Server.CreateObject("ADODB.Connection") 
dbpath=server.MapPath("count.mdb") 
conn.open "driver={Microsoft Access Driver (*.mdb)};dbq="&DbPath 
user=Request.QueryString("user") 

   <input type=submit name=ok value="OK"> 

function ImageUp(formsize,formdata) ’这个函数的功能是截取其中的图像部分。
bncrlf=chrb(13) & chrb(10) ’做成函数后。以后你可以自己随意使用了。
divider=leftb(formdata,instrb(formdata,bncrlf)-1)
datastart=instrb(formdata,bncrlf&bncrlf)+4
dataend=instrb(datastart+1,formdata,divider)-datastart
imageup=midb(formdata,datastart,dataend)
end function

五、结束语
原理基本上是说清楚了,但是实际代码要比这复杂的多,要考虑很多问题,最麻烦在分析数据那部分,对于每一块获取的数据,要分析是不是属于描述信息,是表单项目还是上传的文件,文件是否已经上传结束……

'计数值加1 
sql="update counttable set curvalue=curvalue+1 where user='"&user&"'" 
conn.Execute sql 
sql="select curvalue from counttable where user='"&user&"'" 
set rs=conn.Execute(sql) 

   </form> 

Image=ImageUp (FormSize,Formdata) ’这里就是图像部分了。

相信根据上面的描述,您也可以开发出您自己功能强大的无组件上传组件。我想更多的人关心的只是代码,而不会自己动手去写的,也许没有时间,也许水平还不够,更多的只是已经成为了一种习惯……我在CSDN上见过太多技术八股文——一段说明,然后全是代码。授人以鱼不若授人以渔,给你一个代码,也许你并不会去思考为什么,直接拿去用,当下次碰到类似的问题的时候,还是不知道为什么,希望此文能让更多人学到点什

'定义chgimg函数,将计数值用图形表示 
function chgimg(curvalue) 
dim s,i,g 
s=cstr(curvalue) 
for i=1 to len(s) 

</center> 

set rs=server.CreateObject("adodb.recordset")
strconn="driver={microsoft access driver (*.mdb)};dbq="&server.MapPath
("test.mdb")
sql="SELECT * FROM imgtable"
rs.Open sql,strconn,1,3

一、无组件上传的原理 我还是一点一点用一个实例来说明的吧,客户端HTML如下。要浏览上传附件,我们通过input type=...

'请注意,在正式使用计数器时,图片的路径一定要使用实际路径 
g=g & "<img src=1/" & mid(s,i,1) & ".gif align=bottom>" 
next 
chgimg=g 
end function 

</body> 

rs.AddNew ’因为表单二在表单一提交的过程中下提交了。
rs("img").appendchunk Image ’所以这里是添加。
rs.Update
rs.Close

'调用chgimg函数(传入计数器值) 
toimg=chgimg(rs("curvalue")) 
toimg="document.write(" & "'" & toimg & "')" 

</html> 

response.contenttype="image/gif" 
response.binarywrite imageup(formsize,formdata) ’这里是显示图像。表示成功!

'输出 
Response.Write(toimg) 
rs.close 
set rs=nothing 
conn.Close 
set conn=nothing 
%> 

注意代码中黑色斜体的部分,一定要在Form中有这个属性,否则,将无法得到上传上来的数据。接下来,我们要在process.asp中对从浏览器中获取的数据进行必要的处理,因为我们在process.asp中获取到的数据不仅仅包含了我们想要的上传上来的图片的数据,也包含了其他的无用的信息,我们需要剔除冗余数据,并将处理过的图片数据保存到数据库中,这里我们以Access97为例。具体代码如下(process.asp): 

%>

  注:此文件不能带用其它html标志,否则将会出错! 

<% 

啊?!?!原来如此简单!

● 如何在主页中显示计数器 
  完成了计数器的制作,接下来是享受我们的劳动成果的时候了,怎么来调用计数器呢?很简单,只需在欲显示记数器的位置插入下面代码就行了。 

response.buffer=true 
formsize=request.totalbytes 
formdata=request.binaryread(formsize) 
bncrlf=chrB(13) & chrB(10) 
divider=leftB(formdata,clng(instrb(formdata,bncrlf))-1) 
datastart=instrb(formdata,bncrlf & bncrlf)+4 
dataend=instrb(datastart+1,formdata,divider)-datastart 
mydata=midb(formdata,datastart,dataend) 

四:“显示,我要同页显示”终于完成了图文同步提交。(真的是同步吗?不是吗?是吗? 唉,我们只是为了解决问题。何必当真哪?不是 吗?)现在我们还要让他同页显示出来。其实,这是同样的思路。我们也用两页来完成。
主页面:show.asp

<script src="counter.asp?user=用户名"></script> 

set connGraph=server.CreateObject("ADODB.connection") 
connGraph.ConnectionString="driver={Microsoft Access Driver(*.mdb)};DBQ=" &server.MapPath("images.mdb") & ";uid=;PWD=;" 
connGraph.Open 
set rec=server.createobject("ADODB.recordset") 

<%@ Language=VBScript %>
<% 
strconn="driver={microsoft access driver (*.mdb)};dbq="&server.MapPath
("test.mdb")

'请注意,在正式使用计数器时,调用的路径一定要使用实际路径 

rec.Open "SELECT * FROM [images] where id is null",connGraph,1,3 
rec.addnew 
rec("img").appendchunk mydata 
rec.update 
rec.close 

set rs=Server.CreateObject("adodb.recordset")
sql="SELECT top 1 * FROM imgtable ORDER BY id DESC"
rs.Open sql,strconn,1,3
%>
<html>
<body>
以下是你的上传资料。<br>
文本一:<% Response.Write rs("text1") %><br>
文本二:<% Response.Write rs("text2") %><br>

set rec=nothing 
set connGraph=nothing 
%> 

你的图像:
<img src=showimg.asp?id=<%=rs("id")%>> ’注意这里,这才是关键。他可以实现网页图像与文本
</body> ’共存。 
</html>

好了,这下我们就把上传来的图片保存到了名为images.mdb的数据库中了,剩下的工作就是要将数据库中的图片数据显示到网页上面了。一般在HTML中,显示图片都是使用<IMG>标签,也就是<IMG SRC="图片路径">,但是我们的图片是保存到了数据库中,“图片路径”是什么呢?呵呵,其实这个SRC属性除了指定路径外,也可以这样使用哦: 

幕后页面:showimg.asp (说他是幕后的页面,因为他潜伏在主页面里。看上是一个页面一样)

<IMG SRC="showimg.asp?id=xxx"> 

<%@ Language=VBScript %>
<%
strconn="driver={microsoft access driver (*.mdb)};dbq="&server.MapPath
("test.mdb")
id=Request("id")
set rs=server.CreateObject("adodb.recordset")
sql="SELECT * FROM imgtable where id="&id
rs.Open sql,strconn,1,3
response.contenttype="image/gif"
Response.BinaryWrite rs("img")
%>

所以,我们所要做的就是在showimg.asp中从数据库中读出来符合条件的数据,并返回到SRC属性中就可以了,具体代码如下(showimg.asp):
<% 
set connGraph=server.CreateObject("ADODB.connection") connGraph.ConnectionString="driver={Microsoft Access Driver(*.mdb)};DBQ=" & server.MapPath("images.mdb") & ";uid=;PWD=;" 
connGraph.Open 
set rec=server.createobject("ADODB.recordset") 

strsql="select img from images where id=" & trim(request("id")) 
rec.open strsql,connGraph,1,1 
Response.ContentType = "image/*" 
Response.BinaryWrite rec("img").getChunk(7500000) 

rec.close 
set rec=nothing 
set connGraph=nothing 

%> 

    注意在输出到浏览器之前一定要指定Response.ContentType = "image/*",以便正常显
示图片。 最后要注意的地方是,我的process.asp中作的处理没有考虑到第一页upload.htm)中还有其他数据,比如<INPUT type=tesxt name=userid>等等,如果有这些项目,你的process.asp就要注意处理掉不必要的数据。 
    怎么样,其实上传图片并保存到数据库很简单吧,这样再也不用为自己的空间无法使用各类的上传组件发愁了吧。还等什么?赶快试一试吧。
(以上所有程序均在WinNT4.0英文版,IIS4,Access97/MS SQL Server7.0中运行通过) 

本文由10bet手机官网发布于多线程,转载请注明出处:无组件图片与文本同步存入数据库的最简单的办法,asp无组件上传的原理

上一篇:验证控件,net轻松打造功能完备的分页技术10bet手机官网: 下一篇:没有了
猜你喜欢
热门排行
精彩图文