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

问题描述 投票:0回答:4
html file-upload file-io coldfusion
4个回答
6
投票

在搜索了一些博客文章、遇到了这个问题并阅读了 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>

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

然后,我创建了 uploadFile 函数,它接受 fieldNamedestinationPath 参数。我根据传入的字段获取上传文件的数组,遍历文件以确保目标文件路径不存在(如果存在则使其唯一),然后使用 java.xml 的内容写入目标文件。从临时上传中引用的 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>

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


2
投票

更新:从 ColdFusion 9 开始,这是真的。这已在 ColdFusion 10 中得到纠正。

结束我们的评论对话:

这对于默认的 ColdFusion 行为来说根本不可能。

cffile
不支持处理来自单个
file
元素的多个文件上传。我认为有可能回退到 JAVA 来做到这一点,但我不知道如何做到这一点。

我很想

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


1
投票

fileUploadAll()
/
<cffile action="uploadAll">
允许您上传所有文件,也可以上传
<input type="file" multiple>
.

的多个文件

尽管它总是处理请求的all文件,即它不区分不同的文件输入,您可能希望以不同的方式处理这些文件,例如通过

accept
参数设置不同的允许 MIME 类型或将文件上传到每个输入的不同位置。

因此,我在 Adobe ColdFusionLucee 问题跟踪器 上创建了增强请求。

基本思路是改变

fileUpload()
函数和
<cffile action="upload">
如果表单域有多个文件自动返回一个数组,或者如果这导致兼容性问题,添加一个新的参数
multiple
默认为
false
控制.


0
投票

是的,它适用于 CF-2018。试试这个用于多文件上传。

<cfif isdefined("form.submit")> 
    <cffile 
         action="uploadall" 
         destination="#expandpath(".")#" 
         nameconflict="MakeUnique" 
         accept="image/png,image/jpeg,.png,.jpg,.jpeg"                
         strict="true"
         result="fileUploaded"
         allowedextensions=".png,.jpg,.jpeg" 
    >   
    <cfloop array="#fileUploaded#" item="item">
        <br><cfdump var="#filegetmimetype(item.serverdirectory&'/'&item.serverfile)#">
        <br><a href="<cfoutput>#item.serverfile#</cfoutput>"><cfoutput>#item.serverfile#</cfoutput></a>
    </cfloop>                             
</cfif>
              
<h3>Upload multiple files.</h3> 

<cfform method="POST" action="#CGI.SCRIPT_NAME#" enctype="multipart/form-data">
    <cfinput type="file" name="Images" multiple="multiple" accept="image/jpeg, image/gif, image/png, application/zip" /><br />
    <cfinput type="submit" name=" submit" value="submit"> 
</cfform>
© www.soinside.com 2019 - 2024. All rights reserved.