ColdFusion处理HTML5 <input type ="file"multiple ="multiple"/>

Mic*_*ael 7 coldfusion file-io html5 file-upload

我正在尝试实现一个HTML5输入字段,让用户选择要上传的多个文件.我的表格中有以下内容:

<form method="post" enctype="multipart/form-data" action="index.cfm">
    <input type="file" name="Images" id="Images" multiple="multiple" accept="image/jpeg, image/gif, image/png, application/zip" />
    ...
Run Code Online (Sandbox Code Playgroud)

我可以在浏览器中选择多个文件,然后点击上传,但我不知道如何使用ColdFusion处理表单帖子.我认为以下内容可行,但这只会上传我选择的最后一个文件:

<cfloop list="#attributes.Images#" index="Image">
    <cffile
        destination = "#ExpandPath(Trim(request.TempFolder))#"
        filefield = "Images"
        action = "upload"
        nameconflict = "MakeUnique"
        result = "UploadedTempFile"
    >
    <cfoutput>#UploadedTempFile.serverFile#<br /></cfoutput>
</cfloop>
Run Code Online (Sandbox Code Playgroud)

有人可以向我解释如何遍历通过我的一个表单字段提交的所有文件,以便我可以单独处理这些文件吗?

Tri*_*Lee 5

在搜索了许多博客文章,将其绊倒并阅读Adobe的文档之后,似乎共识是CF10不支持“多个”文件上传支持(除非您正在编写Flash表单)。问题是cffile标记的“ uploadall ”值可能会上载所有文件,但不会返回有关文件的结果数组。

这是我整合的一个函数,该函数利用了底层Java方法并在ACF 10中进行了测试。

<cffunction name="getUploadedFiles" access="public" returntype="struct"
    hint="Gets the uploaded files, grouped by the field name">
    <cfset var local = {
        files = {}, 
        types = "text/plain,text/csv,application/msexcel,application/vnd.ms-excel,application/octet-stream",
        tempFiles = form.getTempFiles(),
        idx = 0} />

    <cfscript>
        arrayEach(form.getPartsArray(), function (field) {
            var local = {fieldName = field.getName(), destinationFile = ""};

            // Make sure the field available in the form is also
            // available for the temporary files
            if (structKeyExists(tempFiles, fieldName)) {

                // Create the files of field array if it doesn't exist
                if (!structKeyExists(files, fieldName)) {
                    files[fieldName] = [];
                }

                // If only 1 file was uploaded, it won't be an array - so make it one
                if (!isArray(tempFiles[fieldName])) {
                    tempFiles[fieldName] = [tempFiles[fieldName]];
                }

                // Check that the form part is a file and within our list of valid types
                if (field.isFile() && listFindNoCase(types, field.getContentType())) {

                    // Compile details about the upload
                    arrayAppend(files[fieldName], {
                        file = tempFiles[fieldName][++idx],
                        filePart = field,
                        filename = field.getFileName(),
                        filepath = field.getFilePath(),
                        contentType = field.getContentType(),
                        tempFile = tempFiles[fieldName][idx].getPath()
                    });
                }
            }
        });
    </cfscript>

    <cfreturn local.files />
</cffunction>
Run Code Online (Sandbox Code Playgroud)

跟随注释,这只是循环遍历所有表单部分,查找文件,并创建一个包含一些有用文件详细信息的数组(并根据我的应用程序要求按特定的内容类型进行过滤)。

然后,我创建了uploadFile函数,该函数接受fieldNamedestinationPath参数。我根据传入的字段获取上载文件的数组,遍历文件以确保目标文件路径不存在(如果存在则使其唯一),然后使用java.io的内容写入目标文件临时上传中引用的.File对象。

<cffunction name="uploadFile" access="public" returntype="array"
    hint="Uploads a file (or multiple files) from the form to the server">
    <cfargument name="fieldName" type="string" required="true" />
    <cfargument name="destinationPath" type="string" required="true" />

    <cfset var local = {files = [], filepaths = [], allFiles = getUploadedFiles()} />

    <cfif structKeyExists(local.allFiles, arguments.fieldName)>
        <cfset local.files = local.allFiles[arguments.fieldName] />
    </cfif>

    <cfloop array="#local.files#" index="local.file">
        <cfset local.file.destinationFile = arguments.destinationPath & local.file.fileName />

        <cfif fileExists(local.file.destinationFile)>
            <cfset local.file.destinationFile = listFirst(local.file.destinationFile, ".") & "_#getTickCount()#.csv" />
        </cfif>

        <cfset fileWrite(local.file.destinationFile, fileRead(local.file.file)) />
        <cfset arrayAppend(local.filePaths, local.file.destinationFile) />
    </cfloop>

    <cfset setActiveFileName(local.filePaths[arrayLen(local.filePaths)]) />

    <cfreturn local.filePaths />
</cffunction>
Run Code Online (Sandbox Code Playgroud)

现在,我可以完全控制所有要上传的文件,并且可以处理所需的结果。


Dan*_*ort 2

更新:从 ColdFusion 9 开始,这是事实。ColdFusion 10 中已更正此问题。

结束我们的评论对话:

这对于默认的 ColdFusion 行为来说是不可能的。cffile不支持处理单个file元素的多个文件上传。我认为有可能回退到 JAVA 来做到这一点,但我不知道如何实现这一点。

我很想cffile action="uploadall"获取所有 HTML5 多文件元素。需要将其归档为 CF10 的 ER :)。