如何在服务器端Classic ASP页面中引用上传的文件?

问题描述 投票:4回答:2

我试图通过Ajax将文件上传到用经典ASP编写的服务器端脚本。

这是相关的HTML和JavaScript代码:

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

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.');
    }
});

我的问题是:如何在我的经典ASP页面(post.asp)中获取对上传文件的引用?

在PHP中有一个全局变量$ _FILES可用,它包含类似于:

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

Classic ASP中有相同的东西吗?


这是帖子页面:

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

这是帖子页面顶部的一个包含:

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
javascript ajax asp-classic
2个回答
1
投票

上传文件后,您可以使用FileSystemObject检查文件是否存在,并通过GetFile方法检索其属性。使用函数来节省空间并返回属性字典,使它们更容易引用:

function getFileInfo(ByVal fileLocation)

    ' Use MapPath to convert to an absolute path

    fileLocation = Server.MapPath(fileLocation)

    ' Set the file system and dictionary objects using reserved words

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

    ' Check that the file exists

    if fileSystem.FileExists(fileLocation) then

        ' Use GetFile to retrieve the files properties

        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

        ' Attributes 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

        ' File not found

        dictionary.add "FileFound",false

    end if

    ' Return the dictionary object

    set getFileInfo = dictionary

    ' Set all objects to nothing

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

end function

要检查文件是否已上载并检索其属性:

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

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

    if fileInfo.item("FileFound") then

        ' Output all the 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

示例输出:

FileFound:是的 属性:32 DateCreated:20/03/2019 12:40:09 DateLastAccessed:20/03/2019 12:40:09 DateLastModified:20/03/2019 12:40:09 开车:C: 姓名:cat.jpg ParentFolder:C:\ inetpub \ wwwroot \ uploads 路径:C:\ inetpub \ wwwroot \ uploads \ cat.jpg ShortName:cat.jpg ShortPath:C:\ inetpub \ wwwroot \ uploads \ cat.jpg 大小:992514 类型:JPEG图像 文件大小为:992514字节 文件类型为:JPEG图像

编辑:继Lankymart的评论后,您可以使用upl.Files对象执行一些初步检查,然后将文件保存到磁盘:

function randomFileName()

    ' Randomize() generates quite a small seed number, so you will generate duplicate
    ' filenames if you upload enough images. To prevent this, prefix a random number
    ' with a unix timestamp.

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

    Randomize()

    ' filename 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

                ' Extract the file extension

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

                ' Generate a random file name

                rndFileName = randomFileName() & "." & fileExt

                ' Everything checks out, save 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

1
投票

这个问题没有多大意义......

我的问题是:

如何在Classic ASP页面(post.asp)中获取对上传文件的引用?

从您发布的代码中可以清楚地看到,您正在使用自定义类来支持上传FileUploader,它会为您解析二进制文件并构建一组表示上传文件的对象(UploadedFile类)。

在您发布的代码中,您正在访问UploadedFile循环中的For Each对象;

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

修正了在End If结束之前For Each失踪的错字。

在该示例中,您的File对象是UploadedFile类对象,其中包含FileUploader在二进制解析期间填充的文件属性。

© www.soinside.com 2019 - 2024. All rights reserved.