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

How can you verify user identity in Firebase when making a call to a cloud function on a

I have integrated Firebase into my React Native app, and I have only enabled anonymous login feature. Currently, I am attempting to invoke a Cloud Function from the app without utilizing the firebase SDK. Instead, I intend to make the call using axios. De ...

Is it possible for the filter with the new date() function to accept formats other than yyyy-mm-dd?

After receiving a response from mydatepicker in the specific format below: { "isRange":false, "singleDate":{ "date":{ "year":2022, "month":5, "day":13 }, "jsDate": ...

How can I allow users to select multiple files with just one input?

Currently, I am able to retrieve a single file from a single input using the following code: $scope.$on("fileSelected", function (event, args) { $scope.$apply(function () { $scope.files.push(args.file); ...

What are the advantages of choosing express.js over Ruby on Sinatra?

Currently brainstorming for a social app and contemplating the switch from my initial option, Sinatra/Ruby to express.js/nodejs. My main focus is on the abundance of open source projects in Ruby that can expedite development. Another major consideration i ...

Access SCSS variable values in Angular HTML or TypeScript files

So, I've been looking into whether it's feasible to utilize the SCSS variable value within HTML or TS in Angular. For instance: Let's say I have a variable called $mdBreakpoint: 992px; stored inside the _variable.scss file. In my HTML cod ...

Ensure the calling object is retained during the resolution of an Angular promise

Identifying the Issue One issue arises when resolving promises in Javascript: the context switches to Window #. This means that referring back to the object resolving the promise becomes tricky because I can't access or modify its variables. The com ...

Invoking an instance method within a static web service method

Is it possible to call a non-static method in the static Web-Method of asp.net? ...

Error: The call stack has reached the maximum size limit in nodejs and reactjs

When I attempt to submit the token received from my registration using the code snippet below, I encounter an error stating "maximum call stack exceeded." exports.activationController = (req, res) => { const { token } = req.body; exports.activation ...

Utilize setState in a ReactJS function within an if statement towards the end

Help needed! I'm facing issues trying to use the function setState within an if statement inside another function. Specifically, I'm working on creating a series of Tab components with inline styles that determine their visibility. Before returni ...

"Facing a dilemma with Javascript's Facebox getElementById function - not fetching any

Utilizing facebox, I am initiating a small modal dialog with a form and attempting to retrieve the value from a text field on that form using javascript. Below is the HTML code: <div id="dialog-form95" style="display:none"> <div class="block"> ...

Ways to conceal the scroll bar upon the initial loading of a webpage

Recently, I created a single-page website consisting of 4 sections. The client has specific requirements that need to be fulfilled: The scrollbar should not be visible when the page loads. Once the user starts scrolling past the second section, the scrol ...

Interacting with the DOM of an iFrame from a separate window using Javascript

My main webpage is hosted on "DomainA" and it contains an iFrame sourced from "DomainB". Within this iFrame, there is a click event that opens a new window, also sourced from "DomainB". I am attempting to update an input field within the iFrame from the n ...

Something is seriously wrong with the datetime in fullcalendar JavaScript

I've been diving into a tutorial for creating a calendar scheduler in asp.net MVC5 from this link. One issue I'm facing is the datetime being passed and stored as the min value in the database (1/1/0001 12:00:00 AM), almost like it's null b ...

Having two identical select2 forms on the same page

Integrating two select2 multi-value select boxes into my Rails application is proving to be a challenge. While the top form functions correctly, the bottom one refuses to work as expected. Despite my attempts at changing IDs and adding new JavaScript cod ...

Ways to verify multiple radio groups to ensure none have been left unchecked

Is there a more elegant solution to check if either "salad" or "side dish" is left unchecked after submission? I currently have a working approach, but it feels overly complex for such a simple task. This is my current method: function radiosChecker(){ l ...

Placing a new item following each occurrence of 'X' in React components

Currently, I am working with a React component that uses Bootstrap's col col-md-4 styles to render a list of items in three columns. However, I am facing an issue where I need to add a clearfix div after every third element to ensure proper display of ...

Having trouble with understanding the usage of "this" in nodejs/js when using it after a callback function within setTimeout

It's quite peculiar. Here is the code snippet that I am having trouble with: var client = { init: function () { this.connect(); return this; }, connect: function () { var clientObj = this; this.socket = ...

Guide on how to load just the content section upon clicking the submit button

Here is an example of my code: <html> <head> <title>Test Loading</title> </head> <body> <div id="header"> This is header </div> <div id="navigation" ...

Issue encountered when attempting to generate a mongoose schema using a JSON document

Can I define this JSON file structure as a mongoose schema? Mongoose lacks an object type, and I'm unsure how to proceed with it. { "Moutainbike": { "Cross": { "size": [ "395 mm", "440 mm", "480 mm", "535 mm" ], "color" ...

What is the best method for storing a model in a database?

Hello, I am currently attempting to save a model to the database. I am simply inputting the value of a title in order to save it, as my id is set to auto increment. However, I have encountered an issue where my attempts have been unsuccessful. Can someone ...