[轉]ASP模拟POST提交请求上传文件

ASP模拟POST提交请求,可以支持文件上传的multipart/form-data表单方式。其实就是熟悉HTTP协议,构造请求头部,原理清晰,关键是细节的构造过程,可以举一反三,推广到其他语言中去。这是相当经典的代码,好好搜藏吧,哈哈!

发送端,构造头部脚本:


< %

Public   Const  adTypeBinary  =   1

Public   Const  adTypeText  =   2

Public   Const  adLongVarBinary  =   205

' 字节数组转指定字符集的字符串

Public   Function  BytesToString(vtData, ByVal strCharset)

    
Dim  objFile

    
Set  objFile  =  Server.CreateObject( " ADODB.Stream " )

    objFile.Type  =  adTypeBinary

    objFile.Open

    
If   VarType (vtData)  =  vbString  Then

        objFile.Write BinaryToBytes(vtData)

    
Else

        objFile.Write vtData

    
End   If

    objFile.Position  =   0

    objFile.Type  =  adTypeText

    objFile.Charset  =  strCharset

    BytesToString  =  objFile.ReadText( - 1 )

    objFile.Close

    
Set  objFile  =   Nothing

End Function

' 字节字符串转字节数组,即经过MidB/LeftB/RightB/ChrB等处理过的字符串

Public   Function  BinaryToBytes(vtData)

    
Dim  rs

    
Dim  lSize

    lSize  =  LenB(vtData)

    
Set  rs  =  Server.CreateObject( " ADODB.RecordSet " )

    rs.Fields.Append  " Content " , adLongVarBinary, lSize

    rs.Open

    rs.AddNew

    rs( " Content " ).AppendChunk vtData

    rs.Update

    BinaryToBytes  =  rs( " Content " ).GetChunk(lSize)

    rs.Close

    
Set  rs  =   Nothing

End Function

' 指定字符集的字符串转字节数组

Public   Function  StringToBytes(ByVal strData, ByVal strCharset)

    
Dim  objFile

    
Set  objFile  =  Server.CreateObject( " ADODB.Stream " )

    objFile.Type  =  adTypeText

    objFile.Charset  =  strCharset

    objFile.Open

    objFile.WriteText strData

    objFile.Position  =   0

    objFile.Type  =  adTypeBinary

    
If   UCase (strCharset)  =   " UNICODE "   Then

        objFile.Position  =   2   ' delete UNICODE BOM

    
ElseIf   UCase (strCharset)  =   " UTF-8 "   Then

        objFile.Position  =   3   ' delete UTF-8 BOM

    
End   If

    StringToBytes  =  objFile.Read( - 1 )

    objFile.Close

    
Set  objFile  =   Nothing

End Function

' 获取文件内容的字节数组

Public   Function  GetFileBinary(ByVal strPath)

    
Dim  objFile

    
Set  objFile  =  Server.CreateObject( " ADODB.Stream " )

    objFile.Type  =  adTypeBinary

    objFile.Open

    objFile.LoadFromFile strPath

    GetFileBinary  =  objFile.Read( - 1 )

    objFile.Close

    
Set  objFile  =   Nothing

End Function

' XML Upload Class

Class XMLUploadImpl

Private  xmlHttp

Private  objTemp

Private  strCharset, strBoundary

Private   Sub  Class_Initialize()

    
Set  xmlHttp  =  Server.CreateObject( " MSXML2.ServerXMLHTTP " )

    
Set  objTemp  =  Server.CreateObject( " ADODB.Stream " )

    objTemp.Type  =  adTypeBinary

    objTemp.Open

    strCharset  =   " GBK "

    strBoundary  =  GetBoundary()

End Sub

Private   Sub  Class_Terminate()

    objTemp.Close

    
Set  objTemp  =   Nothing

    
Set  xmlHttp  =   Nothing

End Sub

' 获取自定义的表单数据分界线

Private   Function  GetBoundary()

    
Dim  ret( 24 )

    
Dim  table

    
Dim  i

    table  =   " ABCDEFGHIJKLMNOPQRSTUVWXZYabcdefghijklmnopqrstuvwxzy0123456789 "

    
Randomize

    
For  i  =   0   To   UBound (ret)

        ret(i)  =   Mid (table,  Int ( Rnd ()  *   Len (table)  +   1 ),  1 )

    
Next

    GetBoundary  =   " __NextPart__  "   &   Join (ret,  Empty )

End Function  

 

Public   Function  Upload(ByVal strURL,ByVal cookiename,ByVal cookiecontent)    ' 改进之后可以输出cookie  session登录,哈哈

    
Call  AddEnd

    xmlHttp.Open  " POST " , strURL,  False

    
if  cookiename <> ""   and  cookiecontent <> ""   then

       xmlHttp.setRequestHeader  " Cookie " ,cookiename & " = " & cookiecontent & " ; path=/;  "      ' 登录的cookie信息,以后可以用用户名 密码来尝试读取登录信息

    
end   if

       xmlHttp.setRequestHeader  " User-Agent " " User-Agent: Mozilla/4.0 (compatible; OpenOffice.org) "       ' 伪装浏览器

       xmlHttp.setRequestHeader  " Connection " " Keep-Alive "

    xmlHttp.setRequestHeader  " Content-Type " " multipart/form-data; boundary= " & strBoundary                ' PHP的问题就出在这里,没有指定分隔符号,自己不会分析读取,哈哈!搞定

    xmlHttp.setRequestHeader  " Content-Length " , objTemp.size

    xmlHttp.Send objTemp

        
If   VarType (xmlHttp.responseBody)  =  (vbByte  Or  vbArray)  Then  

            Upload  =  BytesToString(xmlHttp.responseBody, strCharset) 

        
End   If

End Function

Public   Function  GetResponse()

    GetResponse = xmlHttp.getResponseHeader( " Set-Cookie " )        ' getAllResponseHeaders("Set-Cookie") 获取cookie字符串

End Function

 

' 设置上传使用的字符集

Public   Property   Let  Charset(ByVal strValue)

    strCharset  =  strValue

End Property

' 添加文本域的名称和值

Public   Sub  AddForm(ByVal strName, ByVal strValue)

    
Dim  tmp

    tmp  =   " \r\n--$1\r\nContent-Disposition: form-data; name=""$2""\r\n\r\n$3 "

    tmp  =   Replace (tmp,  " \r\n " , vbCrLf)

    tmp  =   Replace (tmp,  " $1 " , strBoundary)

    tmp  =   Replace (tmp,  " $2 " , strName)

    tmp  =   Replace (tmp,  " $3 " , strValue)

    objTemp.Write StringToBytes(tmp, strCharset)

End Sub

' 设置文件域的名称/文件名称/文件MIME类型/文件路径或文件字节数组

Public   Sub  AddFile(ByVal strName, ByVal strFileName, ByVal strFileType, vtValue)

    
Dim  tmp

    tmp  =   " \r\n--$1\r\nContent-Disposition: form-data; name=""$2""; filename=""$3""\r\nContent-Type: $4\r\n\r\n "

    tmp  =   Replace (tmp,  " \r\n " , vbCrLf)

    tmp  =   Replace (tmp,  " $1 " , strBoundary)

    tmp  =   Replace (tmp,  " $2 " , strName)

    tmp  =   Replace (tmp,  " $3 " , strFileName)

    tmp  =   Replace (tmp,  " $4 " , strFileType)

    objTemp.Write StringToBytes(tmp, strCharset)

    
If   VarType (vtValue)  =  (vbByte  Or  vbArray)  Then

        objTemp.Write vtValue

    
Else

        objTemp.Write GetFileBinary(vtValue)

    
End   If

End Sub

' 设置multipart/form-data结束标记

Private   Sub  AddEnd()

    
Dim  tmp

    
' tmp = Replace("\r\n--$1--\r\n", "$1", strBoundary)

        tmp  =   " \r\n--$1--\r\n "  

        tmp  =   Replace (tmp,  " \r\n " , vbCrLf) 

        tmp  =   Replace (tmp,  " $1 " , strBoundary)

    objTemp.Write StringToBytes(tmp, strCharset)

    objTemp.Position  =   2

End Sub

' 上传到指定的URL,并返回服务器应答

Public   Function  Upload(ByVal strURL)

    
Call  AddEnd

    xmlHttp.Open  " POST " , strURL,  False

    xmlHttp.setRequestHeader  " Content-Type " " multipart/form-data "

    xmlHttp.setRequestHeader  " Content-Length " , objTemp.size

    xmlHttp.Send objTemp

        
If   VarType (xmlHttp.responseBody)  =  (vbByte  Or  vbArray)  Then  

            Upload  =  BytesToString(xmlHttp.responseBody, strCharset) 

        
End   If

End Function

End  Class

% >


< %

' 在包含该文件后用以下代码调用 

' VB code

Dim  UploadData

Set  UploadData  =   New  XMLUploadImpl

UploadData.Charset  =   " gb2312 "

UploadData.AddForm  " Test " " 123456 "   ' 文本域的名称和内容

' UploadData.AddFile "ImgFile", "F:\test.jpg", "image/jpg", GetFileBinary("F:\test.jpg")'图片或者其它文件

UploadData.AddFile  " ImgFile " , Server.MapPath( " test.jpg " ),  " image/jpg " , GetFileBinary(Server.MapPath( " test.jpg " )) ' 图片或者其它文件

Response.Write UploadData.Upload( " http://localhost/receive.asp " ' receive.asp为接收页面

Set  UploadData  =   Nothing

% >

接收端,剥离读取头部字段:

<meta http-equiv="Content-Type" content="text/html; charset=GB2312" />


< %

Sub  BuildUploadRequest(RequestBin)

    
' Get the boundary

    PosBeg  =   1

    PosEnd  =  InstrB(PosBeg,RequestBin,getByteString( chr ( 13 )))

    boundary  =  MidB(RequestBin,PosBeg,PosEnd - PosBeg)

    boundaryPos  =  InstrB( 1 ,RequestBin,boundary)

    

    

    

    
' Get all data inside the boundaries

    
Do  until (boundaryPos = InstrB(RequestBin,boundary  &  getByteString( " -- " )))

        
' Members variable of objects are put in a dictionary object

        
Dim  UploadControl

        
Set  UploadControl  =   CreateObject ( " Scripting.Dictionary " )

        

        
' Get an object name

        Pos  =  InstrB(BoundaryPos,RequestBin,getByteString( " Content-Disposition " ))

        Pos  =  InstrB(Pos,RequestBin,getByteString( " name= " ))

        PosBeg  =  Pos + 6

        PosEnd  =  InstrB(PosBeg,RequestBin,getByteString( chr ( 34 )))    

        Name  =  getString(MidB(RequestBin,PosBeg,PosEnd - PosBeg))

        PosFile  =  InstrB(BoundaryPos,RequestBin,getByteString( " filename= " ))

        PosBound  =  InstrB(PosEnd,RequestBin,boundary)

        

        
' Test if object is of file type

        
If   PosFile <> 0   AND  (PosFile < PosBound)  Then

            

            
' Get Filename, content-type and content of file

            PosBeg  =  PosFile  +   10

            PosEnd  =   InstrB(PosBeg,RequestBin,getByteString( chr ( 34 )))

            FileName  =  getString(MidB(RequestBin,PosBeg,PosEnd - PosBeg))

            

            

            
' Add filename to dictionary object

            UploadControl.Add  " FileName " , FileName

            Pos  =  InstrB(PosEnd,RequestBin,getByteString( " Content-Type: " ))

            PosBeg  =  Pos + 14

            PosEnd  =  InstrB(PosBeg,RequestBin,getByteString( chr ( 13 )))     

            

            

            
' Add content-type to dictionary object

            ContentType  =  getString(MidB(RequestBin,PosBeg,PosEnd - PosBeg))

            UploadControl.Add  " ContentType " ,ContentType

            

            

            
' Get content of object

            PosBeg  =  PosEnd + 4

            PosEnd  =  InstrB(PosBeg,RequestBin,boundary) - 2

            Value  =  MidB(RequestBin,PosBeg,PosEnd - PosBeg)

            
Else

            

            
' Get content of object

            Pos  =  InstrB(Pos,RequestBin,getByteString( chr ( 13 )))

            PosBeg  =  Pos + 4

            PosEnd  =  InstrB(PosBeg,RequestBin,boundary) - 2

            Value  =  getString(MidB(RequestBin,PosBeg,PosEnd - PosBeg))

        
End   If

        

        
' Add content to dictionary object

    UploadControl.Add  " Value "  , Value    

        

        
' Add dictionary object to main dictionary

    UploadRequest.Add name, UploadControl    

        

        
' Loop to next object

        BoundaryPos = InstrB(BoundaryPos + LenB(boundary),RequestBin,boundary)

    
Loop

    

End Sub

< ! -- webbot bot = " PurpleText "  PREVIEW = " end of建立上传数据字典的函数 "   -->

' String to byte string conversion

Function  getByteString(StringStr)

For  i  =   1   to   Len (StringStr)

     char  =   Mid (StringStr,i, 1 )

    getByteString  =  getByteString  &  chrB(AscB(char))

Next

End Function

' Byte string to string conversion(hoho,this can deal with chinese!!!)

Function  getString(str)

strto  =   ""

for  i = 1   to  lenb(str)

if  AscB(MidB(str, i,  1 ))  >   127   then

strto  =  strto  &   chr (Ascb(MidB(str, i,  1 )) * 256 + Ascb(MidB(str, i + 1 1 )))

=  i  +   1

else

strto  =  strto  &   Chr (AscB(MidB(str, i,  1 )))

end   if

next

getString = strto

End Function

Function  getStringold(StringBin)

getString  = ""

For  intCount  =   1   to  LenB(StringBin)

    getString  =  getString  &   chr (AscB(MidB(StringBin,intCount, 1 ))) 

Next

End Function

 

< ! -- webbot bot = " PurpleText "  PREVIEW = " 开始添加到数据库中去 "   -->

Response.Buffer  =   TRUE

Response.Clear

byteCount  =  Request.TotalBytes

' 获得字节数

RequestBin  =  Request.BinaryRead (byteCount)

Dim  UploadRequest

Set  UploadRequest  =   CreateObject ( " Scripting.Dictionary " )

BuildUploadRequest  RequestBin

filepath
=  UploadRequest.Item( " ImgFile " ).Item( " FileName " )    ' 获取上传文件的完整目录名字

compoundpic 
=  UploadRequest.Item( " ImgFile " ).Item( " Value " )

response.write(filepath
& "  size: " & len (compoundpic))

%
>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值