asp技术,经验分享,疑难解答,常用技巧

2009-11-12 17:25
在Asp程序中用Jmail发邮件的比较多,主要是因为多数虚拟主机支持他,其它的支持的较少。下面是一个Jmail发邮件的例子代码:
如果您在自己的机器上试,请下载Jmail.dll,下载解压后,双击Setup.bat 即可完成安装!
<%
On error resume next
Dim JMail, contentId
Set JMail = Server.CreateObject("JMail.Message")
JMail.Charset = "gb2312" ' 邮件字符集,默认为"US-ASCII"
' JMail.ISOEncodeHeaders = False ' 是否进行ISO编码,默认为True
' 发送者信息(可用变量方式赋值)
JMail.From = "someone@51windows.net" ' 发送者地址
JMail.FromName = "海娃" ' 发送者姓名
JMail.Subject = "邮件主题" ' 邮件主题
' 身份验证
JMail.MailServerUserName = "myusername" ' 身份验证的用户名
JMail.MailServerPassword = "mypassword" ' 身份验证的密码
' 设置优先级,范围从1到5,越大的优先级越高,3为普通
JMail.Priority = 3
JMail.AddHeader "Originating-IP", Request.ServerVariables("REMOTE_ADDR")
' 加入一个收件人【变量email:收件人地址】可以同一语句重复加入多个
JMail.AddRecipient("someone@somehost.com")
' 加入附件【变量filename:附件文件的绝对地址,确保用户IUSR_机器名有访问的权限】
' 【参数设置是(True)否(False)为Inline方式】
'contentId = JMail.AddAttachment (Server.MapPath("jmail.asp"), True)
' 邮件主体(HTML(注意信件内链接附件的方式))
JMail.HTMLBody = "<html><head><META content=zh-cn http-equiv=Content-Language><meta http-equiv=""Content-Type"" content=""text/html; charset=gb2312""><style type=text/css>A:link { FONT-SIZE: 9pt; TEXT-DECORATION: none; color: #000000}A:visited {FONT-SIZE: 9pt; TEXT-DECORATION: none; color: #666666}A:hover {COLOR: #ff6600; FONT-SIZE: 9pt; TEXT-DECORATION: underline}BODY {FONT-SIZE: 9pt} --></style></head><body><font color=red>邮件正文</font><br><font color=green>邮件正文</font><br><b>邮件正文</b></body></html>"
' 邮件主体(文本部分)
JMail.Body = "我们的邮件采用了HTML格式,但是您的邮件查看软件可能不支持。。。邮件正文,邮件正文,邮件正文"
' 发送【调用格式:objJMail.Send([username:password@]SMTPServerAddress[:Port])】
JMail.Send("smtp.163.com")
' 关闭并清除对象
JMail.Close()
Set JMail = Nothing
if err.number<>0 then
response.write "发送发送失败!"
else
response.write "邮件发送成功!"
end if
%>
如果您在自己的机器上试,请下载Jmail.dll,下载解压后,双击Setup.bat 即可完成安装!
<%
On error resume next
Dim JMail, contentId
Set JMail = Server.CreateObject("JMail.Message")
JMail.Charset = "gb2312" ' 邮件字符集,默认为"US-ASCII"
' JMail.ISOEncodeHeaders = False ' 是否进行ISO编码,默认为True
' 发送者信息(可用变量方式赋值)
JMail.From = "someone@51windows.net" ' 发送者地址
JMail.FromName = "海娃" ' 发送者姓名
JMail.Subject = "邮件主题" ' 邮件主题
' 身份验证
JMail.MailServerUserName = "myusername" ' 身份验证的用户名
JMail.MailServerPassword = "mypassword" ' 身份验证的密码
' 设置优先级,范围从1到5,越大的优先级越高,3为普通
JMail.Priority = 3
JMail.AddHeader "Originating-IP", Request.ServerVariables("REMOTE_ADDR")
' 加入一个收件人【变量email:收件人地址】可以同一语句重复加入多个
JMail.AddRecipient("someone@somehost.com")
' 加入附件【变量filename:附件文件的绝对地址,确保用户IUSR_机器名有访问的权限】
' 【参数设置是(True)否(False)为Inline方式】
'contentId = JMail.AddAttachment (Server.MapPath("jmail.asp"), True)
' 邮件主体(HTML(注意信件内链接附件的方式))
JMail.HTMLBody = "<html><head><META content=zh-cn http-equiv=Content-Language><meta http-equiv=""Content-Type"" content=""text/html; charset=gb2312""><style type=text/css>A:link { FONT-SIZE: 9pt; TEXT-DECORATION: none; color: #000000}A:visited {FONT-SIZE: 9pt; TEXT-DECORATION: none; color: #666666}A:hover {COLOR: #ff6600; FONT-SIZE: 9pt; TEXT-DECORATION: underline}BODY {FONT-SIZE: 9pt} --></style></head><body><font color=red>邮件正文</font><br><font color=green>邮件正文</font><br><b>邮件正文</b></body></html>"
' 邮件主体(文本部分)
JMail.Body = "我们的邮件采用了HTML格式,但是您的邮件查看软件可能不支持。。。邮件正文,邮件正文,邮件正文"
' 发送【调用格式:objJMail.Send([username:password@]SMTPServerAddress[:Port])】
JMail.Send("smtp.163.com")
' 关闭并清除对象
JMail.Close()
Set JMail = Nothing
if err.number<>0 then
response.write "发送发送失败!"
else
response.write "邮件发送成功!"
end if
%>

2009-9-23 14:06
日文会导致access在搜索时出错,就是内存溢出,在sql下不会有这种问题,要在access下解决的话在储存和读取时用下面的函数
储存
Function jp2code(CodeStr)
jp2code=Replace(Replace(Replace(Replace(Replace(CodeStr,"ガ","j30AC"),"ギ","j30AE"),"グ","j30B0"),"ゲ","j30B2"),"ゴ","j30B4")
jp2code=Replace(Replace(Replace(Replace(Replace(jp2code,"ザ","j30B6"),"ジ","j30B8"),"ズ","j30BA"),"ゼ","j30BC"),"ゾ","j30BE")
jp2code=Replace(Replace(Replace(Replace(Replace(jp2code,"ダ","j30C0"),"ヂ","j30C2"),"ヅ","j30C5"),"デ","j30C7"),"ド","j30C9")
jp2code=Replace(Replace(Replace(Replace(Replace(jp2code,"バ","j30D0"),"ビ","j30D3"),"ブ","j30D6"),"ベ","j30D9"),"ボ","j30DC")
jp2code=Replace(Replace(Replace(Replace(Replace(jp2code,"パ","j30D1"),"ピ","j30D4"),"プ","j30D7"),"ペ","j30DA"),"ポ","j30DD")
jp2code=Replace(jp2code,"ヴ","j30F4")
End Function
读取
Function code2jp(CodeStr)
code2jp=Replace(Replace(Replace(Replace(Replace(CodeStr,"j30AC","ガ"),"j30AE","ギ"),"j30B0","グ"),"j30B2","ゲ"),"j30B4","ゴ")
code2jp=Replace(Replace(Replace(Replace(Replace(code2jp,"j30B6","ザ"),"j30B8","ジ"),"j30BA","ズ"),"j30BC","ゼ"),"j30BE","ゾ")
code2jp=Replace(Replace(Replace(Replace(Replace(code2jp,"j30C0","ダ"),"j30C2","ヂ"),"j30C5","ヅ"),"j30C7","デ"),"j30C9","ド")
code2jp=Replace(Replace(Replace(Replace(Replace(code2jp,"j30D0","バ"),"j30D3","ビ"),"j30D6","ブ"),"j30D9","ベ"),"j30DC","ボ")
code2jp=Replace(Replace(Replace(Replace(Replace(code2jp,"j30D1","パ"),"j30D4","ピ"),"j30D7","プ"),"j30DA","ペ"),"j30DD","ポ")
code2jp=Replace(code2jp,"j30F4","ヴ")
End Function
如果还不好用在下个下面的软件试试..
oBlog3.1 Access数据库日文字符转换程序
适用范围:
本程序只适用于Access数据库,解决日文字符导致搜索时内存溢出的问题
只适用于从3.0beta/3.0/3.1beta1升级到3.1的数据库
直接从3.1版本开始的网站不必执行该程序
使用SQL Server数据库的网站不必执行该程序
注意:
1:请务必备份你的数据库文件!!
2:升级完成后不必重新发布全站
3:升级完成后需要手动压缩一下数据库文件
下载地址:
http://www.oblog.cn/down/oblog31_convertjp.rar
储存
Function jp2code(CodeStr)
jp2code=Replace(Replace(Replace(Replace(Replace(CodeStr,"ガ","j30AC"),"ギ","j30AE"),"グ","j30B0"),"ゲ","j30B2"),"ゴ","j30B4")
jp2code=Replace(Replace(Replace(Replace(Replace(jp2code,"ザ","j30B6"),"ジ","j30B8"),"ズ","j30BA"),"ゼ","j30BC"),"ゾ","j30BE")
jp2code=Replace(Replace(Replace(Replace(Replace(jp2code,"ダ","j30C0"),"ヂ","j30C2"),"ヅ","j30C5"),"デ","j30C7"),"ド","j30C9")
jp2code=Replace(Replace(Replace(Replace(Replace(jp2code,"バ","j30D0"),"ビ","j30D3"),"ブ","j30D6"),"ベ","j30D9"),"ボ","j30DC")
jp2code=Replace(Replace(Replace(Replace(Replace(jp2code,"パ","j30D1"),"ピ","j30D4"),"プ","j30D7"),"ペ","j30DA"),"ポ","j30DD")
jp2code=Replace(jp2code,"ヴ","j30F4")
End Function
读取
Function code2jp(CodeStr)
code2jp=Replace(Replace(Replace(Replace(Replace(CodeStr,"j30AC","ガ"),"j30AE","ギ"),"j30B0","グ"),"j30B2","ゲ"),"j30B4","ゴ")
code2jp=Replace(Replace(Replace(Replace(Replace(code2jp,"j30B6","ザ"),"j30B8","ジ"),"j30BA","ズ"),"j30BC","ゼ"),"j30BE","ゾ")
code2jp=Replace(Replace(Replace(Replace(Replace(code2jp,"j30C0","ダ"),"j30C2","ヂ"),"j30C5","ヅ"),"j30C7","デ"),"j30C9","ド")
code2jp=Replace(Replace(Replace(Replace(Replace(code2jp,"j30D0","バ"),"j30D3","ビ"),"j30D6","ブ"),"j30D9","ベ"),"j30DC","ボ")
code2jp=Replace(Replace(Replace(Replace(Replace(code2jp,"j30D1","パ"),"j30D4","ピ"),"j30D7","プ"),"j30DA","ペ"),"j30DD","ポ")
code2jp=Replace(code2jp,"j30F4","ヴ")
End Function
如果还不好用在下个下面的软件试试..
oBlog3.1 Access数据库日文字符转换程序
适用范围:
本程序只适用于Access数据库,解决日文字符导致搜索时内存溢出的问题
只适用于从3.0beta/3.0/3.1beta1升级到3.1的数据库
直接从3.1版本开始的网站不必执行该程序
使用SQL Server数据库的网站不必执行该程序
注意:
1:请务必备份你的数据库文件!!
2:升级完成后不必重新发布全站
3:升级完成后需要手动压缩一下数据库文件
下载地址:
http://www.oblog.cn/down/oblog31_convertjp.rar
采集程序的主要步骤如下:
一、获取被采集的页面的内容
二、从获取代码中提取所有用的数据
一、获取被采集的页面的内容
我目前所掌握的ASP常用获取被采集的页面的内容方法:
1、用serverXMLHTTP组件获取数据
以下内容为程序代码:
Function GetBody(weburl)
'创建对象
Dim ObjXMLHTTP
Set ObjXMLHTTP=Server.CreateObject("MSXML2.serverXMLHTTP")
'请求文件,以异步形式
ObjXMLHTTP.Open "GET",weburl,False
ObjXMLHTTP.send
While ObjXMLHTTP.readyState <> 4
ObjXMLHTTP.waitForResponse 1000
Wend
'得到结果
GetBody=ObjXMLHTTP.responseBody
'释放对象
Set ObjXMLHTTP=Nothing
End Function
调用方法:
GetBody(文件的URLf地址)
2、或XMLHTTP组件获取数据
以下内容为程序代码:
Function GetBody(weburl)
'创建对象
Set Retrieval = CreateObject("Microsoft.XMLHTTP")
With Retrieval
.Open "Get", weburl, False, "", ""
.Send
GetBody = .ResponseBody
End With
'释放对象
Set Retrieval = Nothing
End Function
调用方法:
GetBody(文件的URLf地址)
这样获取的数据内容还需要进行编码转换才可以使用
以下内容为程序代码:
Function BytesToBstr(body,Cset)
dim objstream
set objstream = Server.CreateObject("adodb.stream")
objstream.Type = 1
objstream.Mode =3
objstream.Open
objstream.Write body
objstream.Position = 0
objstream.Type = 2
objstream.Charset = Cset
BytesToBstr = objstream.ReadText
objstream.Close
set objstream = nothing
End Function
调用方法:BytesToBstr(要转换的数据,编码)'编码常用为GB2312和UTF-8
二、从获取代码中提取所有用的数据
目前我掌握的方法有:
1、用ASP内置的MID函数截取需要的数据
以下内容为程序代码:
Function body(wstr,start,over)
start=Newstring(wstr,start)
'设置需要处理的数据的唯一的开始标记
over=Newstring(wstr,over)
'和start相对应的就是需要处理的数据的唯一的结束标记
body=mid(wstr,start,over-start)
'设置显示页面的范围
End Function
调用方法:body(被采集的页面的内容,开始标记,结束标记)
2、用正则获取需要的数据
以下内容为程序代码:
Function body(wstr,start,over)
Set xiaoqi = New Regexp'设置配置对象
xiaoqi.IgnoreCase = True'忽略大小写
xiaoqi.Global = True'设置为全文搜索
xiaoqi.Pattern = "”&start&“.+?”&over&“"'正则表达式
Set Matches =xiaoqi.Execute(wstr)'开始执行配置
set xiaoqi=nothing
body=""
For Each Match in Matches
body=body&Match.Value '循环匹配
Next
End Function
调用方法:body(被采集的页面的内容,开始标记,结束标记)
采集程序祥细思路:
1、取得网站的分页列表页的每页地址
目前绝大部分动态网站的分页地址都有规则,如:
动态页
第一页:index.asp?page=1
第二页:index.asp?page=2
第三页:index.asp?page=3
.....
静态页
第一页:page_1.htm
第二页:page_2.htm
第三页:page_3.htm
.....
取得网站的分页列表页的每页地址,只需要用变量替代每页地址的变化的字符即可如:page_<%="&page&"%>.htm
2、获取被采集网站的分页列表页内容
3、从分页列表代码中提取被采集的内容页面的URL连接地址
绝大部分分页页面里的内容页连接也有固定规则,如:
连接1
连接2
连接3
用以下代码就可以获得一个URL连接集合
以下内容为程序代码:
Set xiaoqi = New Regexp
xiaoqi.IgnoreCase = True
xiaoqi.Global = True
xiaoqi.Pattern = ””“.+?”““
Set Matches =xiaoqi.Execute(页面列表内容)
set xiaoqi=nothing
url=""
For Each Match in Matches
url=url&Match.Value
Next
4、取得被采集的内容页面内容,根据”提取标记“从被采集的内容页面分别截取要取得的数据
因为是动态生成的页面,大多数内容页面内都有相同的html标记,我们可以根据这些有规则的标记提取需要的各个部分的内容。
如:
每个页面都有网页标题,用我上面写的MID截取函数就可以获得之间的值,也可以用正则表达式来获得。
例:body("","")
一、获取被采集的页面的内容
二、从获取代码中提取所有用的数据
一、获取被采集的页面的内容
我目前所掌握的ASP常用获取被采集的页面的内容方法:
1、用serverXMLHTTP组件获取数据
以下内容为程序代码:
Function GetBody(weburl)
'创建对象
Dim ObjXMLHTTP
Set ObjXMLHTTP=Server.CreateObject("MSXML2.serverXMLHTTP")
'请求文件,以异步形式
ObjXMLHTTP.Open "GET",weburl,False
ObjXMLHTTP.send
While ObjXMLHTTP.readyState <> 4
ObjXMLHTTP.waitForResponse 1000
Wend
'得到结果
GetBody=ObjXMLHTTP.responseBody
'释放对象
Set ObjXMLHTTP=Nothing
End Function
调用方法:
GetBody(文件的URLf地址)
2、或XMLHTTP组件获取数据
以下内容为程序代码:
Function GetBody(weburl)
'创建对象
Set Retrieval = CreateObject("Microsoft.XMLHTTP")
With Retrieval
.Open "Get", weburl, False, "", ""
.Send
GetBody = .ResponseBody
End With
'释放对象
Set Retrieval = Nothing
End Function
调用方法:
GetBody(文件的URLf地址)
这样获取的数据内容还需要进行编码转换才可以使用
以下内容为程序代码:
Function BytesToBstr(body,Cset)
dim objstream
set objstream = Server.CreateObject("adodb.stream")
objstream.Type = 1
objstream.Mode =3
objstream.Open
objstream.Write body
objstream.Position = 0
objstream.Type = 2
objstream.Charset = Cset
BytesToBstr = objstream.ReadText
objstream.Close
set objstream = nothing
End Function
调用方法:BytesToBstr(要转换的数据,编码)'编码常用为GB2312和UTF-8
二、从获取代码中提取所有用的数据
目前我掌握的方法有:
1、用ASP内置的MID函数截取需要的数据
以下内容为程序代码:
Function body(wstr,start,over)
start=Newstring(wstr,start)
'设置需要处理的数据的唯一的开始标记
over=Newstring(wstr,over)
'和start相对应的就是需要处理的数据的唯一的结束标记
body=mid(wstr,start,over-start)
'设置显示页面的范围
End Function
调用方法:body(被采集的页面的内容,开始标记,结束标记)
2、用正则获取需要的数据
以下内容为程序代码:
Function body(wstr,start,over)
Set xiaoqi = New Regexp'设置配置对象
xiaoqi.IgnoreCase = True'忽略大小写
xiaoqi.Global = True'设置为全文搜索
xiaoqi.Pattern = "”&start&“.+?”&over&“"'正则表达式
Set Matches =xiaoqi.Execute(wstr)'开始执行配置
set xiaoqi=nothing
body=""
For Each Match in Matches
body=body&Match.Value '循环匹配
Next
End Function
调用方法:body(被采集的页面的内容,开始标记,结束标记)
采集程序祥细思路:
1、取得网站的分页列表页的每页地址
目前绝大部分动态网站的分页地址都有规则,如:
动态页
第一页:index.asp?page=1
第二页:index.asp?page=2
第三页:index.asp?page=3
.....
静态页
第一页:page_1.htm
第二页:page_2.htm
第三页:page_3.htm
.....
取得网站的分页列表页的每页地址,只需要用变量替代每页地址的变化的字符即可如:page_<%="&page&"%>.htm
2、获取被采集网站的分页列表页内容
3、从分页列表代码中提取被采集的内容页面的URL连接地址
绝大部分分页页面里的内容页连接也有固定规则,如:
连接1
连接2
连接3
用以下代码就可以获得一个URL连接集合
以下内容为程序代码:
Set xiaoqi = New Regexp
xiaoqi.IgnoreCase = True
xiaoqi.Global = True
xiaoqi.Pattern = ””“.+?”““
Set Matches =xiaoqi.Execute(页面列表内容)
set xiaoqi=nothing
url=""
For Each Match in Matches
url=url&Match.Value
Next
4、取得被采集的内容页面内容,根据”提取标记“从被采集的内容页面分别截取要取得的数据
因为是动态生成的页面,大多数内容页面内都有相同的html标记,我们可以根据这些有规则的标记提取需要的各个部分的内容。
如:
每个页面都有网页标题,用我上面写的MID截取函数就可以获得之间的值,也可以用正则表达式来获得。
例:body("","")

2009-8-18 16:48
我们可用下列办法来解决这一问题——但只是能够判断每个电子邮件地址的格式是否有效,并不能保证该地址确实存在。
第一种办法:
<%
'****************************************************
'函数名:ChkMail
'作 用:邮箱格式检测
'参 数:Email ----Email地址
'返回值:True正确,False有误
'****************************************************
Public Function ChkMail(ByVal Email)
Dim Rep,Pmail : ChkMail = True : Set Rep = New RegExp
Rep.Pattern = "([\.a-zA-Z0-9_-]){2,10}@([a-zA-Z0-9_-]){2,10}(\.([a-zA-Z0-9]){2,}){1,4}$"
Pmail = Rep.Test(Email) : Set Rep = Nothing
If Not Pmail Then ChkMail = False
End Function
%>
使用:
If ChkMail("ls535427@2221262.com") = True Then
Response.Write "格式正确"
Else
Response.Write "格式有误"
End If
第二种办法,用下面这个函数进行判断。它会检查邮件地址是否含有“@”,以及“.”是否在“@”后面:
<%
Public Function IsEmail(ByVal PString)
Dim Plt,Pgt : Plt = False : Pgt = False
For x = 2 To Len(PString) - 1
If Mid(PString,x,1) = "@" Then Plt = True
If Mid(PString,x,1) = "." And Plt = True Then Pgt = True
Next
If Plt = True And Pgt = True Then
IsEmail = True
Else
IsEmail = False
End if
End Function
%>
第一种办法:
<%
'****************************************************
'函数名:ChkMail
'作 用:邮箱格式检测
'参 数:Email ----Email地址
'返回值:True正确,False有误
'****************************************************
Public Function ChkMail(ByVal Email)
Dim Rep,Pmail : ChkMail = True : Set Rep = New RegExp
Rep.Pattern = "([\.a-zA-Z0-9_-]){2,10}@([a-zA-Z0-9_-]){2,10}(\.([a-zA-Z0-9]){2,}){1,4}$"
Pmail = Rep.Test(Email) : Set Rep = Nothing
If Not Pmail Then ChkMail = False
End Function
%>
使用:
If ChkMail("ls535427@2221262.com") = True Then
Response.Write "格式正确"
Else
Response.Write "格式有误"
End If
第二种办法,用下面这个函数进行判断。它会检查邮件地址是否含有“@”,以及“.”是否在“@”后面:
<%
Public Function IsEmail(ByVal PString)
Dim Plt,Pgt : Plt = False : Pgt = False
For x = 2 To Len(PString) - 1
If Mid(PString,x,1) = "@" Then Plt = True
If Mid(PString,x,1) = "." And Plt = True Then Pgt = True
Next
If Plt = True And Pgt = True Then
IsEmail = True
Else
IsEmail = False
End if
End Function
%>

2009-8-12 17:32
采用WEB技术实现B/S(浏览器/服务器)结构的管理系统是办公自动化的发展趋势。基于WEB技术的管理系统,由于开发周期短;与用户平台无关;易于实现交互式应用;能对信息进行快速、高效的收集、处理和发布,近几年来得到了迅速发展。而ASP技术由于其开发效率高、交互性好,安全性强等特点,逐渐成为开发管理系统的首选工具。
许多基于WEB的应用都涉及文件上传操作。常见的文件上传技术有:基于HTTP协议的;基于VB(或DELPHI等编程语言)开发的文件上传组件的;基于数据库技术的等等。这些方法一般都需要编程者能同时掌握WEB技术、数据库技术或CGI技术或组件技术,对编程者的要求较高。而本文将介绍的利用ASP技术直接实现文件上传功能则只需编程者掌握单一的ASP技术即可,大大降低了编程难度。
几种文件上传技术的比较
1、基于HTTP协议
该方法需要编程者利用第三方软件,如DELPHI、VB等,在应用程序中先进行HTTP协议编程,然后将待上传文件内容按HTTP协议的格式打包,最后向WEB服务器发送上传的请求报文,从而实现文件的上传。因为DELPHI和VB不能编写完整的WEB网络程序,只能编写WEB小应用程序,因此,该方法只用于功能受限的网络应用。
2、基于VB(或DELPHI等)开发的文件上传组件
该方法利用VB(或DELPHI等编程语言)开发ASP服务器组件,实现特定的文件上传服务。它首先利用ASP表单功能将文件(二进制格式)从用户端上传到服务器端,然后使用VB开发的组件,对二进制文件进行处理,成为可以正常读写的文件。该方法要求编程者不仅掌握ASP语言,而且还能利用VB等第三方语言进行组件编程,增加了开发的难度。
3、基于数据库技术
该方法和上个方法有类似之处。不同的地方在于对上传的二进制文件的处理上。它使用数据库来保存二进制文件。无论是小型数据库还是大型数据库都提供了存储二进制数据的数据类型,只要以Append Chunk方式将数据存入相应的字段就可以了。该方法虽然简单可行,但是因为每次上传的文件大小都是不一样的,因此,会对数据库的空间造成很大的浪费,降低了数据的访问速度;并且使得文件只能在数据库环境下进行访问,造成了很大的不便。
实例分析
但是,利用ASP技术直接实现文件上传功能则只需编程者掌握单一的ASP技术即可,
大大降低了编程难度。下面我们将通过一个实例来介绍如何使用该方法。
1、文件上传表单
首先需要编写一个能提供文件上传功能的表单,程序如下所示:
<Form action="upload.asp" method=post enctype="multipart/form-data">
上传文件:<Input type=file name=file1><br>
<input type=submit name=upload value="上传">
</form>
其中,enctype参数用来设置表单的MIME编码方式,在进行文件(或同时包含文本框)上传时,必须将其属性设置为"multipart/form-data";upload.asp是服务器端对接收到的二进制文件流进行处理的ASP程序,在本文的后面将陆续介绍其内容。
2、上传文件格式分析
在处理文件之前,我们要先了解上传的文件的具体格式,通过编写下面一段简单的ASP程序就可以查看其二进制代码:
<%
filesize=Request.TotalBytes '获得上传文件的大小
filedata=Request.BinaryRead(filesize) '获得上传文件的二进制数据
Response.BinaryWrite filedata '在浏览器上显示二进制数据
%>
分析浏览器上显示的上传文件的二进制代码,发现代码包括四个部分(若同时上传多个文件或文本框,则代码按上传的先后次序排列,格式相同),每一部分的内容是用回车换行符号来进行分隔的:
1)第一部分(起始标志)
-----------------------------7d329631b04d4
2)第二部分(文件说明)
Content-Disposition: form-data; name="file1"; filename="C:\Documents and Settings\Administrator\My Documents\Invitation.doc" Content-Type: application/msWord
在此,我们可以获得上传文件的文件名称及绝对路径,也可以获得文件类型。这些信息是正确保存文件所不可缺少的。
3)第三部分(文件内容)
即文件的二进制内容,略。
4)第四部分(结束标志)
-----------------------------7d329631b04d4
结合第一部分和第四部分的内容来看,"-----------------------------7d329631b04d4"(每次上传,数值都不一样)起到了分割符的作用,它标志着一段数据(当有多个上传内容时)的开始和结束。从保存文件所需要的信息来讲,我们首先需要从第二部分数据的"filename"中获得文件名称,然后需要正确定位文件的起始位置,最后利用ASP技术将二进制文件用本来的文件名保存即可。若同时上传多个内容(如多个文本框和文件),也是按同样的方法处理,每部分的内容都包含在分割符之中,只是文本框和文件的表现形式稍有不同,这可以通过具体分析其二进制代码来了解。
3、利用ASP技术实现文件存储
上传文件代码的处理
1) 获得分割符代码
从上面的分析我们已经知道,分割符起到了分割多个数据段(包括文本框和各种类型的文件)的重要作用。前面已经分析过,分割符出现在第一个回车换行符号前。因此,通过下面这段程序就可获得分割符代码:
<%
newline=chrB(13) & chrB(10) 'newline表示二进制的回车符
filesize=Request.TotalBytes 'filesize是上传文件的大小
filedata=Request.BinaryRead(filesize) 'filedata是上传文件的二进制数据
divider=leftB(filedata,clng(instrb(filedata,newline))-1) 'divider是分割符
%>
注:因为这里处理的都是二进制字节码,因此,所有的函数都是使用它的二进制版本,加了"b "。
2) 获得文件(或文本框)内容
(1) 预备函数(将二进制串转化成字符串)
上传文件的内容不需要经过二进制向字符串的转换过程,直接保存就可。但是,若需提取文本框内容或文件的名称,就必须进行转换。因此,需要编写一个通用的,并且适用于汉字的转换函数。以下是该函数代码:
Function BtoS (bstr)
If not Is Null (bstr) Then
for i = 0 to lenb(bstr) - 1
bchr = midb(bstr,i+1,1)
If ascb(bchr)>127 Then '汉字是双字节,得两个字符一起处理
temp = temp&chr(ascw(midb(bstr, i+2, 1)&bchr))
i = i+1
Else
temp = temp&chr(ascb(bchr))
End If
next
End If
BtoS = temp
End Function
(2) 获得文件(或文本框)内容
在实际的WEB应用中,上传操作可能涉及多项内容,如多个文本框、多个文件等等。文件和文本框很好区分,文件的数据中包含了"filename="字串。因此,我们写了如下的通用函数,既可用于提取文件内容,又可提取文本框内容(需进行二进制转换):
Function getdata(byval data, byval divider, final) 'data表示二进制串;divider表示分割符;final表示数据的结束位置
filename=chrb(102)&chrb(105)&chrb(108)&chrb(101)&chrb(110)&chrb(97)&chrb(109)&chrb(101)&chrb(61)&chrb(34) '字符串"filename"的二进制表示
bncrlf=chrb(13)&chrb(10) '二进制的回车符
startpos = instrb(data,divider)+lenb(divider)+lenb(bncrlf) ' 开始位置
endpos = instrb(startpos,data, divider)-lenb(bncrlf) '结束位置
part1 = midb(data, startpos, endpos-startpos) '两个分割符之间的内容
firstline = midb(part1, 1, instrb(part1, bncrlf)-1) ' 内容之前的说明段
If (instrb(firstline,filename)=0) Then '若为文本框,获得文本框字符串内容
stemp=midb(part1,instrb(part1,bncrlf&bncrlf)+lenb(bncrlf&bncrlf),lenb(part1)-instrb(part1,bncrlf&bncrlf)+lenb(bncrlf&bncrlf))
getdata=BtoS(stemp)
Else '若为文件,获得文件二进制内容
Getdata=midb (part1, instrb (part1, bncrlf&bncrlf)+lenb (bncrlf&bncrlf), lenb (part1)
-instrb(part1,bncrlf&bncrlf)+lenb(bncrlf&bncrlf))
End If
Final=endpos
End function
在程序中直接调用该函数就可获得所需文件(或文本框)内容,如下所示:
<%
Content=getdata (data, divider, position)
%>
3) 获得文件名称
前面已经分析过了,上传文件数据流的"filename="字段里包含了文件的名称和绝对路 径。一般来说,我们只需提取出路径中的文件名即可,以下是程序代码:
<%
namepos=instrrev(B2S(firstline),chr(92)) 'firstline即上面获得的说明部分数据,chr(92)
表示"/"
filename=midb(firstline,namepos+1,lenb(firstline)-namepos-1) '获得文件名称
%>
利用ASP直接实现文件上传功能
传统的ASP程序员只能利用FILESYSTEMOBJECT对象对文本文件(.txt)进行移动、复制、删除等操作,若需处理二进制对象,则不得不采用本文前面介绍的那些方法来实现。但是,现在ASP中的ADO.STREAM对象可以同时操作文本对象和二进制对象(可以在http://www.microsoft.com/data下载),利用它就可以在ASP中直接实现文件上传功能。下面,我们就介绍其实现过程。
1)打开STREAM对象
对于SREAM对象而言,若要进行文件的保存,则必须是将该对象的全部内容进行保存。因此,我们必须要创建两个(或多个)STREAM对象,其中一个为源数据流,即接收初始的二进制数据;另一个为目的数据流,即接收来自经源数据流处理后的数据,并最终保存为所需的文件。
<%
set str=Server.CreateObject("ADODB.Stream") 'str为源数据流
str.Mode=3 '设置打开模式,3为可读可写
str.Type=1 '设置数据类型,1为二进制数据
str.Open
set desc=server.CreateObject("ADODB.Stream") 'desc为目标数据流
desc.Mode=3
Desc.Type=1
desc.Open
%>
2)STEAM对象间内容的复制
在该部分,必须在源数据流中定位文件开始的位置,并且求出文件内容的长度,才能将文件正确的复制到目的数据流中,并且保存文件,程序代码如下:
<%
formdata=Request.BinaryRead(Request.TotalBytes) 'formdata为上传的所有内容
str.Write formdata ' 赋值源数据流
str.position=count-lenb(result)-2 'position指出文件的开始位置
str.copyto desc, lenb(filecotent) 'lenb(filecontent)表示文件的长度
desc.SaveToFile fullpath,2 '以fullpath指定的路径及名称保存文件
%>
3)关闭STEAM对象
编程完成后,应关闭并释放STEAM对象,如下所示:
<%
Desc. Close
Set desc=nothing
Str. Close
Set STR=nothing
%>
总结
本文给出了利用ASP直接实现文件上传的方法,在本单位自行开发的信息管理系统中得到了很好的应用。实践证明:与传统的几种文件上传方法相比,该方法更简便、更高效。
许多基于WEB的应用都涉及文件上传操作。常见的文件上传技术有:基于HTTP协议的;基于VB(或DELPHI等编程语言)开发的文件上传组件的;基于数据库技术的等等。这些方法一般都需要编程者能同时掌握WEB技术、数据库技术或CGI技术或组件技术,对编程者的要求较高。而本文将介绍的利用ASP技术直接实现文件上传功能则只需编程者掌握单一的ASP技术即可,大大降低了编程难度。
几种文件上传技术的比较
1、基于HTTP协议
该方法需要编程者利用第三方软件,如DELPHI、VB等,在应用程序中先进行HTTP协议编程,然后将待上传文件内容按HTTP协议的格式打包,最后向WEB服务器发送上传的请求报文,从而实现文件的上传。因为DELPHI和VB不能编写完整的WEB网络程序,只能编写WEB小应用程序,因此,该方法只用于功能受限的网络应用。
2、基于VB(或DELPHI等)开发的文件上传组件
该方法利用VB(或DELPHI等编程语言)开发ASP服务器组件,实现特定的文件上传服务。它首先利用ASP表单功能将文件(二进制格式)从用户端上传到服务器端,然后使用VB开发的组件,对二进制文件进行处理,成为可以正常读写的文件。该方法要求编程者不仅掌握ASP语言,而且还能利用VB等第三方语言进行组件编程,增加了开发的难度。
3、基于数据库技术
该方法和上个方法有类似之处。不同的地方在于对上传的二进制文件的处理上。它使用数据库来保存二进制文件。无论是小型数据库还是大型数据库都提供了存储二进制数据的数据类型,只要以Append Chunk方式将数据存入相应的字段就可以了。该方法虽然简单可行,但是因为每次上传的文件大小都是不一样的,因此,会对数据库的空间造成很大的浪费,降低了数据的访问速度;并且使得文件只能在数据库环境下进行访问,造成了很大的不便。
实例分析
但是,利用ASP技术直接实现文件上传功能则只需编程者掌握单一的ASP技术即可,
大大降低了编程难度。下面我们将通过一个实例来介绍如何使用该方法。
1、文件上传表单
首先需要编写一个能提供文件上传功能的表单,程序如下所示:
<Form action="upload.asp" method=post enctype="multipart/form-data">
上传文件:<Input type=file name=file1><br>
<input type=submit name=upload value="上传">
</form>
其中,enctype参数用来设置表单的MIME编码方式,在进行文件(或同时包含文本框)上传时,必须将其属性设置为"multipart/form-data";upload.asp是服务器端对接收到的二进制文件流进行处理的ASP程序,在本文的后面将陆续介绍其内容。
2、上传文件格式分析
在处理文件之前,我们要先了解上传的文件的具体格式,通过编写下面一段简单的ASP程序就可以查看其二进制代码:
<%
filesize=Request.TotalBytes '获得上传文件的大小
filedata=Request.BinaryRead(filesize) '获得上传文件的二进制数据
Response.BinaryWrite filedata '在浏览器上显示二进制数据
%>
分析浏览器上显示的上传文件的二进制代码,发现代码包括四个部分(若同时上传多个文件或文本框,则代码按上传的先后次序排列,格式相同),每一部分的内容是用回车换行符号来进行分隔的:
1)第一部分(起始标志)
-----------------------------7d329631b04d4
2)第二部分(文件说明)
Content-Disposition: form-data; name="file1"; filename="C:\Documents and Settings\Administrator\My Documents\Invitation.doc" Content-Type: application/msWord
在此,我们可以获得上传文件的文件名称及绝对路径,也可以获得文件类型。这些信息是正确保存文件所不可缺少的。
3)第三部分(文件内容)
即文件的二进制内容,略。
4)第四部分(结束标志)
-----------------------------7d329631b04d4
结合第一部分和第四部分的内容来看,"-----------------------------7d329631b04d4"(每次上传,数值都不一样)起到了分割符的作用,它标志着一段数据(当有多个上传内容时)的开始和结束。从保存文件所需要的信息来讲,我们首先需要从第二部分数据的"filename"中获得文件名称,然后需要正确定位文件的起始位置,最后利用ASP技术将二进制文件用本来的文件名保存即可。若同时上传多个内容(如多个文本框和文件),也是按同样的方法处理,每部分的内容都包含在分割符之中,只是文本框和文件的表现形式稍有不同,这可以通过具体分析其二进制代码来了解。
3、利用ASP技术实现文件存储
上传文件代码的处理
1) 获得分割符代码
从上面的分析我们已经知道,分割符起到了分割多个数据段(包括文本框和各种类型的文件)的重要作用。前面已经分析过,分割符出现在第一个回车换行符号前。因此,通过下面这段程序就可获得分割符代码:
<%
newline=chrB(13) & chrB(10) 'newline表示二进制的回车符
filesize=Request.TotalBytes 'filesize是上传文件的大小
filedata=Request.BinaryRead(filesize) 'filedata是上传文件的二进制数据
divider=leftB(filedata,clng(instrb(filedata,newline))-1) 'divider是分割符
%>
注:因为这里处理的都是二进制字节码,因此,所有的函数都是使用它的二进制版本,加了"b "。
2) 获得文件(或文本框)内容
(1) 预备函数(将二进制串转化成字符串)
上传文件的内容不需要经过二进制向字符串的转换过程,直接保存就可。但是,若需提取文本框内容或文件的名称,就必须进行转换。因此,需要编写一个通用的,并且适用于汉字的转换函数。以下是该函数代码:
Function BtoS (bstr)
If not Is Null (bstr) Then
for i = 0 to lenb(bstr) - 1
bchr = midb(bstr,i+1,1)
If ascb(bchr)>127 Then '汉字是双字节,得两个字符一起处理
temp = temp&chr(ascw(midb(bstr, i+2, 1)&bchr))
i = i+1
Else
temp = temp&chr(ascb(bchr))
End If
next
End If
BtoS = temp
End Function
(2) 获得文件(或文本框)内容
在实际的WEB应用中,上传操作可能涉及多项内容,如多个文本框、多个文件等等。文件和文本框很好区分,文件的数据中包含了"filename="字串。因此,我们写了如下的通用函数,既可用于提取文件内容,又可提取文本框内容(需进行二进制转换):
Function getdata(byval data, byval divider, final) 'data表示二进制串;divider表示分割符;final表示数据的结束位置
filename=chrb(102)&chrb(105)&chrb(108)&chrb(101)&chrb(110)&chrb(97)&chrb(109)&chrb(101)&chrb(61)&chrb(34) '字符串"filename"的二进制表示
bncrlf=chrb(13)&chrb(10) '二进制的回车符
startpos = instrb(data,divider)+lenb(divider)+lenb(bncrlf) ' 开始位置
endpos = instrb(startpos,data, divider)-lenb(bncrlf) '结束位置
part1 = midb(data, startpos, endpos-startpos) '两个分割符之间的内容
firstline = midb(part1, 1, instrb(part1, bncrlf)-1) ' 内容之前的说明段
If (instrb(firstline,filename)=0) Then '若为文本框,获得文本框字符串内容
stemp=midb(part1,instrb(part1,bncrlf&bncrlf)+lenb(bncrlf&bncrlf),lenb(part1)-instrb(part1,bncrlf&bncrlf)+lenb(bncrlf&bncrlf))
getdata=BtoS(stemp)
Else '若为文件,获得文件二进制内容
Getdata=midb (part1, instrb (part1, bncrlf&bncrlf)+lenb (bncrlf&bncrlf), lenb (part1)
-instrb(part1,bncrlf&bncrlf)+lenb(bncrlf&bncrlf))
End If
Final=endpos
End function
在程序中直接调用该函数就可获得所需文件(或文本框)内容,如下所示:
<%
Content=getdata (data, divider, position)
%>
3) 获得文件名称
前面已经分析过了,上传文件数据流的"filename="字段里包含了文件的名称和绝对路 径。一般来说,我们只需提取出路径中的文件名即可,以下是程序代码:
<%
namepos=instrrev(B2S(firstline),chr(92)) 'firstline即上面获得的说明部分数据,chr(92)
表示"/"
filename=midb(firstline,namepos+1,lenb(firstline)-namepos-1) '获得文件名称
%>
利用ASP直接实现文件上传功能
传统的ASP程序员只能利用FILESYSTEMOBJECT对象对文本文件(.txt)进行移动、复制、删除等操作,若需处理二进制对象,则不得不采用本文前面介绍的那些方法来实现。但是,现在ASP中的ADO.STREAM对象可以同时操作文本对象和二进制对象(可以在http://www.microsoft.com/data下载),利用它就可以在ASP中直接实现文件上传功能。下面,我们就介绍其实现过程。
1)打开STREAM对象
对于SREAM对象而言,若要进行文件的保存,则必须是将该对象的全部内容进行保存。因此,我们必须要创建两个(或多个)STREAM对象,其中一个为源数据流,即接收初始的二进制数据;另一个为目的数据流,即接收来自经源数据流处理后的数据,并最终保存为所需的文件。
<%
set str=Server.CreateObject("ADODB.Stream") 'str为源数据流
str.Mode=3 '设置打开模式,3为可读可写
str.Type=1 '设置数据类型,1为二进制数据
str.Open
set desc=server.CreateObject("ADODB.Stream") 'desc为目标数据流
desc.Mode=3
Desc.Type=1
desc.Open
%>
2)STEAM对象间内容的复制
在该部分,必须在源数据流中定位文件开始的位置,并且求出文件内容的长度,才能将文件正确的复制到目的数据流中,并且保存文件,程序代码如下:
<%
formdata=Request.BinaryRead(Request.TotalBytes) 'formdata为上传的所有内容
str.Write formdata ' 赋值源数据流
str.position=count-lenb(result)-2 'position指出文件的开始位置
str.copyto desc, lenb(filecotent) 'lenb(filecontent)表示文件的长度
desc.SaveToFile fullpath,2 '以fullpath指定的路径及名称保存文件
%>
3)关闭STEAM对象
编程完成后,应关闭并释放STEAM对象,如下所示:
<%
Desc. Close
Set desc=nothing
Str. Close
Set STR=nothing
%>
总结
本文给出了利用ASP直接实现文件上传的方法,在本单位自行开发的信息管理系统中得到了很好的应用。实践证明:与传统的几种文件上传方法相比,该方法更简便、更高效。




