20119 月6
VB实现自动上传文件网页ActiveX控件(模拟form提交)
网页中实现自动上传本地文件,而不需要用户选择,这种应用场景很多,例如业务系统中需要使用的二代身份证扫描器、一体机(扫描仪)、摄像头拍照等。
首先介绍一个国外网站:http://www.planet-source-code.com/ 里面有许多可用的源代码供参考,搜索 upload file 找到 vb6 file uploader (类似的代码比较多,这个是比较好的一个)。
VB通过模拟HTTP POST过程把文件提交至服务器。
Dim WinHttpReq As WinHttp.WinHttpRequest
Const HTTPREQUEST_SETCREDENTIALS_FOR_SERVER = 0
Const HTTPREQUEST_SETCREDENTIALS_FOR_PROXY = 1
Const BOUNDARY = "Xu02=$"
Const HEADER = "--Xu02=$"
Const FOOTER = "--Xu02=$--"
Function UploadFiles(DirPath As String, strFileName As Variant, strFileForm As Variant, strURL As String, _
Optional postName As Variant, Optional postVar As Variant, Optional strUserName As String, _
Optional strPassword As String) As String
Dim fName As String
Dim strFile As String
Dim strBody As String
Dim aPostBody() As Byte
Dim nFile As Integer
Dim p As Integer
Set WinHttpReq = New WinHttpRequest
' Turn error trapping on
On Error GoTo SaveErrHandler
' Assemble an HTTP request.
WinHttpReq.Open "POST", strURL, False
If strUserName <> "" And strPassword <> "" Then
' Set the user name and password, for server request authentication
WinHttpReq.SetCredentials strUserName, strPassword, _
HTTPREQUEST_SETCREDENTIALS_FOR_SERVER
End If
'-------------------------- Becareful not to mingle too much here -----------------------------------
' Set the header
WinHttpReq.SetRequestHeader "Content-Type", "multipart/form-data; boundary=" & BOUNDARY
' Assemble the body
' Starting tag
strBody = HEADER
For i = 0 To UBound(strFileName)
' Grap the name
fName = strFileName(i)
' Grap the file
strFile = GetFile(DirPath & "\" & fName)
strBody = strBody & vbCrLf & "Content-Disposition: form-data; name=""" & strFileForm(i) & _
"""; filename=""" & fName & """ " & vbCrLf & "Content-type: file" & _
vbCrLf & vbCrLf & strFile & vbCrLf
If i < UBound(strFileName) Then
' This is boundary tag between two files
strBody = strBody & "--Xu02=$"
End If
strFile = ""
Next i
'Posted Variable
For p = 0 To UBound(postName)
strBody = strBody & HEADER & vbCrLf
strBody = strBody & "Content-Disposition: form-data; name=""" & postName(p) & """" & vbCrLf & vbCrLf
strBody = strBody & postVar(p) & vbCrLf
'Debug.Print "-----------------------------------------------------------------------------------------------------"
'Debug.Print "Content-Disposition: form-data; name=""" & postName(p) & """" & vbCrLf & vbCrLf & postVar(p) & vbCrLf
'Debug.Print "-----------------------------------------------------------------------------------------------------"
Next p
' Ending tag
strBody = strBody & FOOTER
' Because of binary zeros, post body has to convert to byte array
aPostBody = StrConv(strBody, vbFromUnicode)
' Send the HTTP Request.
WinHttpReq.Send aPostBody
' Display the status code and response headers.
'debug.print WinHttpReq.GetAllResponseHeaders & " " & WinHttpReq.ResponseText
UploadFiles = WinHttpReq.ResponseText
Debug.Print "[UploadScript::UploadFiles]" & vbCrLf & WinHttpReq.ResponseText
Set WinHttpReq = Nothing
Exit Function
SaveErrHandler:
Debug.Print "[UploadScript::UploadFiles]" & vbCrLf & Err.Description
UploadFiles = WinHttpReq.ResponseText
Set WinHttpReq = Nothing
End Function
Function GetFile(strFileName As String) As String
Dim strFile As String
' Grap the file
nFile = FreeFile
Open strFileName For Binary As #nFile
strFile = String(LOF(nFile), " ")
Get #nFile, , strFile
Close #nFile
GetFile = strFile
End Function
'-----------------------------------------------------------
Private Sub Command1_Click()
Dim pst As New clsUploadEngine
'file path (make sure put "\" after folder name)
filepath = App.Path & "\sample\"
'filename array
filearr = Array("scenery1.jpg", "scenery2.jpg", "scenery3.jpg")
'form file post name (equivalent to <input type="file" name="filename">
fileform = Array("fileA", "fileB", "fileC")
'url to post file/information
uploadurl = "http://127.0.0.1:8080/savefile.jsp"
'post parameter & posted variable (optional)
'if no post parameter, just put dummy post, if not error will occur
postparam = Array("id", "uname", "passwd", "op")
postVar = Array("1", "root", "", "tdrupload")
pst.UploadFiles CStr(filepath), filearr, fileform, CStr(uploadurl), postparam, postVar
End Sub
在此基础上,做成ActiveX控件即可。但问题是这个源码上传到服务器的文本文件虽然看起来正常但文件结尾会有空编码、图片损坏。囧。
后来发现 WebNoteEditor 可以实现粘贴QQ截图,自动把文件上传到服务器,于是联系作者。作者是个好人哈,分享了一些经验甚至代码。目前在作者的帮助下,已实现的网页控件的文件自动上传功能,可传多个文件、多表单项。
下面要解决如何在线安装的问题了……