在搜索了一些博客文章、遇到了这个问题并阅读了 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 函数,它接受 fieldName 和 destinationPath 参数。我根据传入的字段获取上传文件的数组,遍历文件以确保目标文件路径不存在(如果存在则使其唯一),然后使用 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>
现在我可以完全控制所有正在上传的文件,并且可以处理所需的结果。
更新:从 ColdFusion 9 开始,这是真的。这已在 ColdFusion 10 中得到纠正。
结束我们的评论对话:
这对于默认的 ColdFusion 行为来说根本不可能。
cffile
不支持处理来自单个 file
元素的多个文件上传。我认为有可能回退到 JAVA 来做到这一点,但我不知道如何做到这一点。
我很想
cffile action="uploadall"
抓取所有HTML5 多文件元素。需要将其归档为 CF10 的 ER :).
fileUploadAll()
/<cffile action="uploadAll">
允许您上传所有文件,也可以上传<input type="file" multiple>
.的多个文件
尽管它总是处理请求的all文件,即它不区分不同的文件输入,您可能希望以不同的方式处理这些文件,例如通过
accept
参数设置不同的允许 MIME 类型或将文件上传到每个输入的不同位置。
因此,我在 Adobe ColdFusion 和 Lucee 问题跟踪器 上创建了增强请求。
基本思路是改变
fileUpload()
函数和<cffile action="upload">
如果表单域有多个文件自动返回一个数组,或者如果这导致兼容性问题,添加一个新的参数multiple
默认为false
控制.
是的,它适用于 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>