无组件实现ASP上传 - 表单数据的解析

通常我们用enctype="multpart/form-data"的form来实现上传文件,但如果表单中有多个文件甚至还有其他内容的话,如何来解析表单呢?
当表单POST到服务器端后,我们可以用Request对象的BinaryRead对象还读取表单的数据。这个表单的数据有如下结构:
  <表单域分隔符><表单域内容><表单域分隔符><表单域内容><表单域分隔符>......
其中,表单域分隔符是随机生成的,整个表单都使用同一个表单域分隔符。我们只要通过寻找第一个CRLR(即ChrB(13) + ChrB(10))就可以得到表单域分隔符。
表单域内容的结构如下:
如果是文件域
  name="<表单项的名字>"filename="<文件路径>"Content-Type:<文件内容>
如果是文本域
  name="<表单项的名字>"<文本域内容>
知道了表单的数据结构,我们就能轻松地把表单中的内容解析出来了。
以下ASP代码实现了一个解析表单类,有兴趣的可以试试看。
<% ' 文件域类 Class FileField Public szFilePath, szContentType, inFileSize, cbFileData Private Sub Class_Initialize() End Sub Private Sub Class_Terminate() End Sub End Class ' enctype="multpart/form-data" 的表单类 Class MultipartForm Private cbBinData, cbSptr, cbCrLf ' 构造函数 Private Sub Class_Initialize() inBinSize = Request.TotalBytes cbBinData = Request.BinaryRead(inBinSize) cbCrLf = ChrB(13) + ChrB(10) ' 表单域分隔符 cbSptr = MidB(cbBinData, 1, InStrB(cbBinData, cbCrLf) - 1) End Sub ' 析构函数 Private Sub Class_Terminate() End Sub ' 从表单中读取域 Public Function FormField(szFieldName) ' 根据 szFieldName 从表单中分离出域的内容 inFieldStrat = InStrB(cbBinData, StringToBinary("name=" + Chr(34) + szFieldName +Chr(34))) If inFieldStrat = 0 Then FormField = "" Exit Function End If inFieldLen = InStrB(inFieldStrat, cbBinData, cbSptr) - inFieldStrat If inFieldLen = 0 Then FormField = "" Exit Function End If cbField = MidB(cbBinData, inFieldStrat, inFieldLen) ' 尝试查找 filename inFileNameStart = InStrB(cbField, StringToBinary("filename=" + Chr(34))) If inFileNameStart = 0 Then ' 没有找到 filename, 说明是文本域, 返回文本域内容 inDataStart = InStrB(cbField, cbCrLf + cbCrLf) + 4 inDataLen = LenB(cbField) - inDataStart - 1 FormField = BinaryToString(MidB(cbField, inDataStart)) Else ' 找到了 filename, 创建一个 FileField 对象用于返回 Set FormField = New FileField ' 获取文件路径 inFileNameStart = inFileNameStart + 10 inFileNameLen = InStrB(inFileNameStart, cbField, ChrB(34) + cbCrLf) - inFileNameStart FormField.szFilePath = BinaryToString(MidB(cbField, inFileNameStart, inFileNameLen)) ' 获取 Content-Type 内容 inContentTypeStart = InStrB(cbField, StringToBinary("Content-Type:")) + 13 inContentTypeLen = InStrB(inContentTypeStart, cbField, cbCrLf) - inContentTypeStart FormField.szContentType = BinaryToString(MidB(cbField, inContentTypeStart, inContentTypeLen)) ' 获取 文件内容 inFileDataStart = InStrB(cbField, cbCrLf + cbCrLf) + 4 inFileDataLen = LenB(cbField) - inFileDataStart - 1 FormField.inFileSize = inFileDataLen FormField.cbFileData = MidB(cbField, inFileDataStart, inFileDataLen) End If End Function ' 二进制串转字符串函数 Private Function BinaryToString(cbBinData) For I =1 To LenB(cbBinData) cbTmp= AscB(MidB(cbBinData, I, 1)) If Not (cbTmp > 127) Then szStr = szStr + Chr(cbTmp) Else I = I + 1 cbTmpL = AscB(MidB(cbBinData,I,1)) szStr = szStr + Chr(cbTmp * 256 + cbTmpL) End If Next BinaryToString = szStr End Function ' 字符串转二进制串函数 Private Function StringToBinary(szStrData) For I = 1 To Len(szStrData) szTemp = CStr(Hex(Asc(Mid(szStrData, I, 1)))) If Len(szTemp) = 2 Then cbTemp = cbTemp + ChrB(Clng("&H" + Trim(szTemp))) Else cbTemp = cbTemp + ChrB(Clng("&H" + Mid(Trim(szTemp), 1, 2))) cbTemp = cbTemp + ChrB(Clng("&H" + Mid(Trim(szTemp), 3, 2))) End If Next StringToBinary = cbTemp End Function End Class %>

测试代码如下(假设POST过来的表单中有一个名叫image1的文件域):
<% Set mfForm = New MultipartForm Set ffFile = mfForm.FormField("image1") Response.ContentType = ffFile.szContentType Response.BinaryWrite ffFile.cbFileData %>

你可能感兴趣的:(asp,class,function,image,数据结构,hex)