What is the process for accessing an uploaded file in a server-side Classic ASP page?

I'm attempting to use Ajax to upload a file to a server-side script in classic ASP.

Here is the relevant HTML and JavaScript code:

<input type="file" id="fileInput" />

and

function saveToServer(file) {
    const fd = new FormData();
    fd.append('image', file);
    const xhr = new XMLHttpRequest();
    xhr.open('POST', 'http://localhost/post.asp', true);
    xhr.onload = () => {
        if (xhr.status === 200) {
            // Do stuff with response
        }
    };
    xhr.send(fd);
}

const fileInput = document.getElementById("fileInput");

fileInput.addEventListener("change", () => {
    const file = fileInput.files[0];
    if (/^image\//.test(file.type)) {
        saveToServer(file);
    } else {
        console.warn('You can only upload images.');
    }
});

My concern is: how do I access the uploaded file on my Classic ASP page (post.asp)?

In PHP, there's a global variable called $_FILES that would contain something like:

Array
(
  [image] => Array
  (
    [name] => cat.png
    [type] => image/png
    [tmp_name] => /tmp/phpOjXMW3
    [error] => 0
    [size] => 10603
  )
)

Is there an equivalent in Classic ASP?


This is the post page:

Set upl = New FileUploader 
upl.Upload()
If upl.Files.Count = 1 Then
  For Each File In upl.Files.Items
    If File.FileSize < 100000 Then
      File.FileName =  upl.Form ("id") & ".jpg"
      File.SaveToDisk Server.MapPath("/Images")
  next
end if

This is an include at the top of the post page:

Class FileUploader
    Public  Files
    Private mcolFormElem

    Private Sub Class_Initialize()
        Set Files = Server.CreateObject("Scripting.Dictionary")
        Set mcolFormElem = Server.CreateObject("Scripting.Dictionary")
    End Sub

    Private Sub Class_Terminate()
        If IsObject(Files) Then
            Files.RemoveAll()
            Set Files = Nothing
        End If
        If IsObject(mcolFormElem) Then
            mcolFormElem.RemoveAll()
            Set mcolFormElem = Nothing
        End If
    End Sub

    Public Property Get Form(sIndex)
        Form = ""
        If mcolFormElem.Exists(LCase(sIndex)) Then Form = mcolFormElem.Item(LCase(sIndex))
    End Property

    Public Default Sub Upload()
        Dim biData, sInputName
        Dim nPosBegin, nPosEnd, nPos, vDataBounds, nDataBoundPos
        Dim nPosFile, nPosBound
    'response.Flush

        biData = Request.BinaryRead(Request.TotalBytes)
        nPosBegin = 1
        nPosEnd = InstrB(nPosBegin, biData, CByteString(Chr(13)))

        If (nPosEnd-nPosBegin) <= 0 Then Exit Sub

        vDataBounds = MidB(biData, nPosBegin, nPosEnd-nPosBegin)
        nDataBoundPos = InstrB(1, biData, vDataBounds)

        Do Until nDataBoundPos = InstrB(biData, vDataBounds & CByteString("--"))

            nPos = InstrB(nDataBoundPos, biData, CByteString("Content-Disposition"))
            nPos = InstrB(nPos, biData, CByteString("name="))
            nPosBegin = nPos + 6
            nPosEnd = InstrB(nPosBegin, biData, CByteString(Chr(34)))
            sInputName = CWideString(MidB(biData, nPosBegin, nPosEnd-nPosBegin))
            nPosFile = InstrB(nDataBoundPos, biData, CByteString("filename="))
            nPosBound = InstrB(nPosEnd, biData, vDataBounds)

            If nPosFile <> 0 And  nPosFile < nPosBound Then
                Dim oUploadFile, sFileName
                Set oUploadFile = New UploadedFile

                oUploadFile.FormElement = MidB(biData, nPos, 5)


                nPosBegin = nPosFile + 10
                nPosEnd =  InstrB(nPosBegin, biData, CByteString(Chr(34)))
                sFileName = CWideString(MidB(biData, nPosBegin, nPosEnd-nPosBegin))
                oUploadFile.FileName = Right(sFileName, Len(sFileName)-InStrRev(sFileName, "\"))

                nPos = InstrB(nPosEnd, biData, CByteString("Content-Type:"))
                nPosBegin = nPos + 14
                nPosEnd = InstrB(nPosBegin, biData, CByteString(Chr(13)))

                oUploadFile.ContentType = CWideString(MidB(biData, nPosBegin, nPosEnd-nPosBegin))

                nPosBegin = nPosEnd+4
                nPosEnd = InstrB(nPosBegin, biData, vDataBounds) - 2
                oUploadFile.FileData = MidB(biData, nPosBegin, nPosEnd-nPosBegin)

                If oUploadFile.FileSize > 0 Then Files.Add LCase(sInputName), oUploadFile
            Else
                nPos = InstrB(nPos, biData, CByteString(Chr(13)))
                nPosBegin = nPos + 4
                nPosEnd = InstrB(nPosBegin, biData, vDataBounds) - 2
                If Not mcolFormElem.Exists(LCase(sInputName)) Then mcolFormElem.Add LCase(sInputName), CWideString(MidB(biData, nPosBegin, nPosEnd-nPosBegin))
            End If

            nDataBoundPos = InstrB(nDataBoundPos + LenB(vDataBounds), biData, vDataBounds)
        Loop
    End Sub

    'String to byte string conversion
    Private Function CByteString(sString)
        Dim nIndex
        For nIndex = 1 to Len(sString)
           CByteString = CByteString & ChrB(AscB(Mid(sString,nIndex,1)))
        Next
    End Function

    'Byte string to string conversion
    Private Function CWideString(bsString)
        Dim nIndex
        CWideString =""
        For nIndex = 1 to LenB(bsString)
           CWideString = CWideString & Chr(AscB(MidB(bsString,nIndex,1))) 
        Next
    End Function
End Class

Class UploadedFile
    Public ContentType
    Public FileName
    Public FileData
    Public FormElement

    Public Property Get FileSize()
        FileSize = LenB(FileData)
    End Property

    Public Sub SaveToDisk(sPath)
        Dim oFS, oFile
        Dim nIndex

        If sPath = "" Or FileName = "" Then Exit Sub
        If Mid(sPath, Len(sPath)) <> "\" Then sPath = sPath & "\"

        Set oFS = Server.CreateObject("Scripting.FileSystemObject")
        If Not oFS.FolderExists(sPath) Then Exit Sub

        Set oFile = oFS.CreateTextFile(sPath & FileName, True)

        For nIndex = 1 to LenB(FileData)
            oFile.Write Chr(AscB(MidB(FileData,nIndex,1)))
        Next

        oFile.Close
    End Sub

    Public Sub SaveToDatabase(ByRef oField)
        If LenB(FileData) = 0 Then Exit Sub

        If IsObject(oField) Then
            oField.AppendChunk FileData
        End If
    End Sub

End Class

Answer №1

This question may be a bit confusing...

I am wondering:

How do I obtain a reference to the uploaded file in my Classic ASP page (post.asp)?

Based on the provided code, it appears that you are utilizing a custom class called FileUploader to handle the file upload process, which decodes the binary data and creates objects representing the uploaded files (specifically the UploadedFile class).

In your code snippet, you are iterating through the collection of UploadedFile objects within a For Each loop;

Set upl = New FileUploader 
upl.Upload()
If upl.Files.Count = 1 Then
  For Each File In upl.Files.Items
    If File.FileSize < 100000 Then
      File.FileName =  upl.Form ("id") & ".jpg"
      File.SaveToDisk Server.MapPath("/Images")
    End If
  Next
End If

Correction: Added missing End If before the end of the For Each loop.

In this scenario, the referenced File object represents an instance of the UploadedFile class that encapsulates the file attributes obtained during the binary parsing by the FileUploader.

Answer №2

When a file is uploaded, you can utilize the FileSystemObject with the GetFile method to confirm the file's existence and retrieve its properties. To streamline this process, create a function that returns a dictionary of properties for easier reference:

function getFileInfo(ByVal fileLocation)

    ' Use MapPath to convert to an absolute path

    fileLocation = Server.MapPath(fileLocation)

    ' Initialize file system and dictionary objects using reserved words

    set fileSystem = Server.CreateObject("Scripting.FileSystemObject")
    Set dictionary = Server.CreateObject("Scripting.Dictionary")

    ' Check if the file exists

    if fileSystem.FileExists(fileLocation) then

        ' Retrieve the file's properties using GetFile

        set file = fileSystem.GetFile(fileLocation)

        ' Add each property to the dictionary object

        dictionary.add "FileFound",true
        dictionary.add "Attributes",file.Attributes
        dictionary.add "DateCreated",file.DateCreated
        dictionary.add "DateLastAccessed",file.DateLastAccessed
        dictionary.add "DateLastModified",file.DateLastModified
        dictionary.add "Drive",file.Drive
        dictionary.add "Name",file.Name
        dictionary.add "ParentFolder",file.ParentFolder
        dictionary.add "Path",file.Path
        dictionary.add "ShortName",file.ShortName
        dictionary.add "ShortPath",file.ShortPath
        dictionary.add "Size",file.Size
        dictionary.add "Type",file.Type

        ' Attribute translations:
        ' 0 = Normal file
        ' 1 = Read-only file
        ' 2 = Hidden file
        ' 4 = System file
        ' 16 = Folder or directory
        ' 32 = File has changed since last backup
        ' 1024 = Link or shortcut
        ' 2048 = Compressed file

    else

        dictionary.add "FileFound",false

    end if

    ' Return the dictionary object

    set getFileInfo = dictionary

    ' Release all objects

    set fileSystem = nothing
    set dictionary = nothing
    set file = nothing

end function

To verify an uploaded file and access its properties:

Dim fileInfo : Set fileInfo = getFileInfo("../../uploads/cat.jpg")  

    ' getFileInfo("/Images/" & upl.Form ("id") & ".jpg") 

    if fileInfo.item("FileFound") then

        ' Display all file properties

        for each item in fileInfo
            response.write "<b>" & item & "</b>: " & fileInfo.item(item) & "<br>"
        next

        ' Output a specific file property

        response.write "<b>The file size is</b>: " & fileInfo.item("Size") & " bytes<br>"
        response.write "<b>The file type is</b>: " & fileInfo.item("Type") & "<br>"

    else

        response.write "File not found"

    end if

Set fileInfo = nothing

Sample output:

FileFound: True
Attributes: 32
DateCreated: 20/03/2019 12:40:09
DateLastAccessed: 20/03/2019 12:40:09
DateLastModified: 20/03/2019 12:40:09
Drive: C:
Name: cat.jpg
ParentFolder: C:\inetpub\wwwroot\uploads
Path: C:\inetpub\wwwroot\uploads\cat.jpg
ShortName: cat.jpg
ShortPath: C:\inetpub\wwwroot\uploads\cat.jpg
Size: 992514
Type: JPEG image
The file size is: 992514 bytes
The file type is: JPEG image


EDIT: Expanding on Lankymart's suggestion, you can incorporate the upl.Files object for initial checks before saving the file:

function randomFileName()

    ' In order to avoid duplicate filenames when uploading multiple images, prefix a random number with a unix timestamp.

    Dim uts : uts = DateDiff("s","1970-01-01 00:00:00",Now())

    Randomize()

    ' File name format: [unix timestamp][random 7 digit number]

    randomFileName = cStr(uts & Int((9999999-1000000+1)*Rnd+1000000))

end function

function validExtension(ByVal allowed, ByVal fileName)

    Dim extRegexp : Set extRegexp = New RegExp

    extRegexp.Pattern = "^.*\.(" & lCase(allowed) & ")$"
    validExtension = extRegexp.Test(lCase(fileName))

end function

if Request.TotalBytes > 0 then

    Const max_upload_size = 100000 ' bytes
    Const allowed_extensions = "jpg|jpeg|png"
    Const upload_folder = "/Images/"

    Dim upload_successful : upload_successful = false
    Dim upload_message : upload_message = ""
    Dim rndFileName, fileExt, fileSplit

    Dim upl : Set upl = New FileUploader 
    upl.Upload()

    If upl.Files.Count = 1 Then

        For Each File In upl.Files.Items

            file.ContentType = lCase(file.ContentType)
            File.FileName = trim(File.FileName)

            if NOT (file.ContentType = "image/jpeg" _
            OR file.ContentType = "image/jpg" _
            OR file.ContentType = "image/png") then

                upload_message = "Invalid file type"

            elseif NOT validExtension(allowed_extensions,File.FileName) then

                upload_message = "Invalid file type"

            elseif File.FileSize > max_upload_size then

                upload_message = "File too big"

            else

                ' Obtain the file extension

                fileSplit = split(File.FileName,".")
                fileExt = lCase(fileSplit(uBound(fileSplit)))

                ' Generate a unique file name

                rndFileName = randomFileName() & "." & fileExt

                ' Proceed to save the file to disk

                File.FileName = rndFileName
                File.SaveToDisk Server.MapPath(upload_folder)

                upload_message = "Upload successful"

                upload_successful = true

            end if

        next

    else

        upload_message = "Maximum upload count exceeded"

    end if

    Set upl = nothing

    ' Return a JSON string      

    Response.ContentType = "application/json"

    response.write _
    "{""uploaded"":" & lCase(upload_successful) & "," &_
    """message"":""" & upload_message & """," &_
    """file"":""" & upload_folder & rndFileName & """}"

end if

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Alter the configuration of a JSON object

I'm currently working on modifying the following JSON text. It has the structure as shown below: { "cabecera": { "tipo_cambio": "", "fecha_emision": "", "total": "" }, "detalle": { "940b130369614bd6b687dc5b41623439": { " ...

What are the steps to fix the "Invariant Violation" issue that is linked to the redux store?

During my DOM testing to verify if a dialog box would open upon clicking a button, I encountered an error message: Invariant Violation: Could not find "store" in either the context or props of >"Connect(Photos)". Either wrap the root component in a , ...

When submitting data through jQuery.ajax that includes the string "???", the value is transformed into "jQuery19107363727174233645_1373301489648?"

Server side script: var configuration = {"NumberOfCPUs":"2","NumberOfCores":"4","OSType":"Linux","OSVersion":"???"}; var identifier = 0; var responseReceived = false; //sending data to the server: $.ajax( { ...

Encountering ECONNREFUSED error when making requests to an external API in a NextJS application integrated with Auth

Currently, I have integrated Auth0 authentication into my NextJS application by following their documentation. Now, I am in the process of calling an external ExpressJS application using the guidelines provided here: https://github.com/auth0/nextjs-auth0/b ...

Navigating race conditions within Node.js++]= can be challenging, but there are strategies

In the process of developing a MERN full stack application, I encountered a scenario where the frontend initiates an api call to "/createDeckOfCards" on my NodeJS backend. The main objective is to generate a new deck of cards upon clicking a button and the ...

Tips for retrieving the most recent UI updates after the container has been modified without the need to refresh the browser

Currently, I have developed a micro frontend application in Angular using module federation. This application is hosted in production with Docker containers. My main concern revolves around how to update the UI changes for the user without them needing to ...

`The challenge of navigating within Material UI tabs in a React js project`

In my current project, I am utilizing React Js along with the Material UI Tabs component to switch between two different components. However, I have encountered an issue where when I navigate to Tab 2 or Tab 1 by clicking on them, the route changes and th ...

import the JSONP file from the local directory and assign it to a variable on

My current setup involves a local webpage that is loading a large JSON database file by utilizing a file named data.jsonp that contains data={a JSON dictionary of information}. I then import this file in my HTML using <script src="data.jsonp"& ...

Customize bullet list icons to adjust in size based on content using css

In my CMS project, the CMS team has a special requirement regarding unordered and ordered lists. They want the size of the bullet list icon to adjust according to the text content within the list. The image below shows the default design of a list item: ...

Transferring the data entered into an input field to a PHP script, in order to retrieve and display the value with JavaScript, unfortunately results in a

My situation involves a form that consists of only one input text field (search_term) and a submit button. The goal is to enter a keyword into the input field, click Submit, have the keyword sent to a php script for json encoding, and then returned back t ...

Once the record has been successfully inserted on the index.aspx page, the function will redirect to the Ajax success method in Asp

When I insert a record on the index.aspx page and redirect to the ajax success function, the message should display alert("success"). I created the function addProject() to handle this task. Surprisingly, there were no errors during the process of adding t ...

JavaScript: Trouble with statement execution

My code is designed to classify a point as 1 if it's above the line y=x, and -1 if it's below the line y=x. I visually represent this line in a canvas by plotting y=x (although due to invertion on the y-axis, it appears like y=-x). For each point ...

Formulate a Generic Type using an Enum

I'm currently working on a project that involves creating a generic Type using enums. Enum export enum OverviewSections { ALL = 'all', SCORE = 'score_breakdown', PERFORMANCE = 'performance_over_time', ENGAGEMENT ...

What is the best way to increase the value of a variable using jQuery?

As I work on adding dates to a slider, I find myself needing to increment the values with each click. Initially, I start with the year - 2. $('#adddates').click(function() { var year = 2; $("#slider").dateRangeSlider({ bounds: { ...

How to clear input fields in Ant Design ReactJS components

Utilizing the form list component from antd in my react.js project https://ant.design/components/form/#Form.List I have a basic form list set up where I can easily add or remove fields. At times, I need to reset the form and remove any additional items t ...

PHP variable not receiving Ajax variable

As a beginner in Ajax and jQuery, I am learning through Stack Overflow and online tutorials. Please be considerate of my novice level as you read and potentially offer advice on my post. I have successfully created a form that displays a message upon subm ...

Displaying a random number triggers a snackbar notification in a ReactJS application

Currently, I am utilizing the notistack package to display a snackbar on the screen. However, when calling the Snack component with enqueuesnackbar, a random number is displayed along with the snackbar. I'm looking to eliminate this random number fro ...

Transforming the text to be "unreadable"

I find myself in a rather odd predicament where I must display my name and contact details on a webpage. Although I am comfortable with sharing this information, I would prefer that it remain unreadable to robots or other unauthorized sources. Essentially ...

What could be causing my asynchronous JavaScript/Node.js function to bypass a significant portion of the code?

Upon calling the function below: async function sql_func(){ console.log('anothertest') async () => { console.log('third test') try { await sql.connect('heres the connection data') ...

What is the process for validating the CSS background-image URL using Javascript?

The concept here is to verify the URL of the CSS element's id (.boot). If the URL matches, which it does, then it should display "hello world." However, despite everything seeming correct, the expected behavior is not occurring, and the reason behind ...