0

I'm trying to upload a plain text file to a classic asp page and getting an error.

<p>Microsoft VBScript runtime </font> <font face="Arial" size=2>error '800a01a8'</font>
<p>
<font face="Arial" size=2>Object required: 'fields(...)'</font>

Html Code

<form action="upload.asp" method=post ENCTYPE="multipart/form-data">
      File :
<input type="file" class="form_field" name="File1" accept="image/jpeg">
<input type="submit" class="form_pb" Name="Action" value="Send File">
</form>

Vba Code to set the post variable and send the request.

    Const STR_BOUNDARY  As String = "a832972453175"
    Dim nFile           As Integer
    Dim baBuffer()      As Byte
    Dim sPostData       As String
....

'--- read file
nFile = FreeFile
Open sFileName For Binary Access Read As nFile
    If LOF(nFile) > 0 Then
        ReDim baBuffer(0 To LOF(nFile) - 1) As Byte
        Get nFile, , baBuffer
        sPostData = StrConv(baBuffer, vbUnicode)
    End If
Close nFile

sPostData = "--" & STR_BOUNDARY & vbCrLf & _
        "Content-Disposition: form-data; name=""File1""; filename=""" & Mid$(sFileName, InStrRev(sFileName, "\") + 1) & """" & vbCrLf & _
            "Content-Type: text/plain" & vbCrLf & vbCrLf & _
            sPostData & vbCrLf & vbCrLf & _
            STR_BOUNDARY & vbCrLf & _
            "Content-Disposition: form-data; name=""Action""" & vbCrLf & _
             vbCrLf & "Send File" & vbCrLf & _
            "--" & STR_BOUNDARY & "--"

With WinHttpReq

'UPLOAD REQUEST
.Open "POST", sUrl, False
.setRequestHeader "Content-Type", "multipart/form-data; boundary=" & STR_BOUNDARY
.setRequestHeader "User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
.Send (sPostData)
end with

I have access to the source code of the page that is a classic asp page and the upload is executed with a vbscript running at the server.

The error is that the File1 argument = "" and then the upload doesnt start.

Despite the attribute accept in the html code is only for "image/jpeg" I can upload normally when navigating with a browser.

I think is something wrong with my sPostData variable in Vba code.

The file with the upload functions is here: https://www.royalholloway.ac.uk/resources/ASP/PStruh-CZ/1.3/upload.inc

Anyone can see what am I doing wrong?

4
  • The error points to Object required: 'fields(...)' the provided code shows no mention of the fields collection so I would suggest you're looking in the wrong place. Did the error not contain a page name and line number? Commented Mar 18, 2015 at 14:58
  • The error is caused because the result of the function GetUpload at the file upload.inc is empty. Like I posted there is a condition to start the upload (if Fields("File1").FileName = "" do nothing else start the upload) Commented Mar 18, 2015 at 15:26
  • I don't think that will ever work like that, your trying to pass in effect what is binary multipart data as a string. The multipart form post handles all the boundary information you can't pass that before it's processed, you'll just end up with a malformed multipart. Try viewing the request using Fiddler to see what the RAW request looks like. Commented Mar 18, 2015 at 16:01
  • I viewed the request with Firebug. And I set the sPostData to be like the request in the browser. I will create a similar page with the same server-side code and then maybe find out something. Thanks. Commented Mar 18, 2015 at 16:33

2 Answers 2

1

I created a copy of the upload page and looked for something wrong. I found out that the boundary reconigzed by the page was "myboundary" + ;Charset=UTF-8.

The solution in this case is add the charset in the request header.

With WinHttpReq

'UPLOAD REQUEST
.Open "POST", sUrl, False
.setRequestHeader "Content-Type", "multipart/form-data; Charset=UTF-8;boundary=" & STR_BOUNDARY
.setRequestHeader "User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
.Send (sPostData)
end with

.setRequestHeader "Content-Type", "multipart/form-data; Charset=UTF-8; boundary=" & STR_BOUNDARY

Sign up to request clarification or add additional context in comments.

Comments

0

Today I discovered I can upload files (either text or binary) from VBA Excel (could be Word, MSAccess or Outlook too) through standard POST (at least it works for small files). First, it opens a file in a byte array. Second, it converts the byte array to a Base64 String. Third, it uses an IE object to fill a form and submit it, with no direct user interaction.

Public Function UploadFileTo(sourceFile As String, uURL As String, nameFieldID As String, dataFieldID As String, formID As String) As Boolean
    UploadFileTo = False
    ''---------------------------
    Dim nome As String, dados64
    Dim bs() As Byte
    nome = Dir(sourceFile)
    If (nome = "") Then Exit Function
    ''
    bs = ReadFile2("" & sourceFile) ' loads the file into a byte array
    dados64 = Base64Encode(bs) ' encodes it to base64 and returns as String
    ''
    Dim ie As InternetExplorerMedium
    'Dim ie 'As Object
    Dim docweb As Object
    Set ie = New InternetExplorerMedium
    'Set ie = CreateObject("InternetExplorerMedium")
    'Set ie = GetObject("new:{D5E8041D-920F-45e9-B8FB-B1DEB82C6E5E}")
    ie.Navigate2 uURL
    ie.Visible = True
    While ie.Busy: DoEvents: Wend
    While ie.ReadyState <> 4: DoEvents: Wend
    ''
    Set docweb = ie.Document
    docweb.all(nameFieldID).Value = nome
    docweb.all(dataFieldID).Value = dados64
    docweb.all(formID).Submit
    While ie.Busy: DoEvents: Wend
    While ie.ReadyState <> READYSTATE_COMPLETE: DoEvents: Wend
    ''
    ie.Quit
    ''---------------------------
    UploadFileTo = True
End Function

For example: to call the following page:

if UploadFileTo("C:\myPath\myFile.txt", "http://www.website.com/page.html", "myFileNameField", "myFileData", "myDistantForm") then
    MsgBox "File Uploaded successfully"
else
    MsgBox "Failed."
end if

It calls the URL http://www.website.com/page.html

<html>
 <head>
  <title>Sending files within POST with base64 encoding</title>
 </head>
 <body>
  <form id="myDistantForm" action="teste.cgi" method="POST">
   Name: <input type="text" id="finame" name="arq_nome" value="">    <br>
   Data: <textarea name="myFileNameField" id="fidata" rows="30" cols="120"></textarea> <br>
   <input type="submit" name="myFileData" value="Send the File"> <br>
  </form>
 </body>
</html>

IMPORTANT: The server must be able to decode a Base64-encoded string and, then, save the decoded data into a file in the desired server directory, using the given name (or some auto-generated, unique name), no matter if the target server runs ASP, PHP, JSP, CGI/ISAPI or whatever.

To read any file to a Byte array: how can I read a binary file using VBA?

To encode that array into a Base64 String: How do I base64 encode a string efficiently using Excel VBA?

1 Comment

Well... to adapt it to use in Classic ASP, you can follow my response adapting it by removing everything related to Excel. Or just go through its essence: first, load the file in a byte array, then convert this data in a Base64 string, then send this string to the destination page (as a common FORM request, not as in a upload form). The server must be able to decode the base64 String and save it in a file with the same name and extension. At least, it was tested with small files, including videos. Text files also work very well.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.