ColdFusion无法读取Ajax发送的FormData
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ColdFusion无法读取Ajax发送的FormData相关的知识,希望对你有一定的参考价值。
我正在创建一个文件上传组件,我可以将<cfinclude>
放到任何我的CFM页面上,它允许标准文件选择和拖放功能。
选择文件并提交表单时,没有问题,因为我的ColdFusion代码依赖于Form范围来检索文件。
为了使用拖放功能发送文件,我使用jQuery通过Ajax发送请求,根据当前表单发送FormData
。
$form.on('submit', function(e) {
e.preventDefault();
// Get FormData based on form and append the dragged and dropped files
var ajaxData = new FormData($form.get(0));
if (droppedFiles) {
$.each(droppedFiles, function(i, file) {
ajaxData.append($('input[type=file]').attr('name'), file);
});
}
$.ajax({
url: $form.attr('action'),
type: $form.attr('method'),
cache: false,
contentType:false,
processData: false,
success: function(data) {
if (data.SUCCESS) uploadSuccessful($form);
else
{
console.error(data.ERROR);
}
},
error: function(jqXHR, textStatus, errorThrown) {
console.error('Error: File upload unsuccessful ' + errorThrown);
},
data: ajaxData,
dataType: 'json',
dataFilter: function(data, type){
return data.substring(2, data.length);
}
});
});
html:
<form class="file-upload-container" method="post" action="upload.cfm" enctype="multipart/form-data">
<label class="file-upload-input">
<i class="fa fa-upload" aria-hidden="true" style="font-size:5em;"></i><br/><br/>
<input type="file" name="attachment" id="attachment" />
</label>
<div class="file-upload-controls">
<input type="button" id="cancelUpload" value="Cancel" class="btn btn-green" />
<input type="submit" id="upload" value="Upload" class="btn btn-green" />
</div>
</form>
action
的<form>
将发布到我的upload.cfm页面。
我首先验证发布的表单是否有一个名为“attachment”的元素:
<cfif structKeyExists(form, "attachment")>
<!--- This always passes since I'm posting the form with the submit button --->
</cfif>
然后我尝试检索文件名,以便我可以与接受的文件类型进行比较,上传文件,重命名文件,并在我的数据库中插入一个条目。我遇到问题的地方是我试图从发布的FormData
对象(甚至整个文件的内容......)中获取文件名。
<cffunction name="GetTheFileName" access="public" returntype="string" output="false" >
<cfargument name="fieldName" required="true" type="string" hint="Name of the Form field" />
<cfset var tmpPartsArray = Form.getPartsArray() />
<cfif IsDefined("tmpPartsArray")>
<cfloop array="#tmpPartsArray#" index="local.tmpPart">
<cfif local.tmpPart.isFile() AND local.tmpPart.getName() EQ arguments.fieldName>
<cfreturn LCase(local.tmpPart.getFileName()) />
</cfif>
</cfloop>
</cfif>
<cfreturn "" />
</cffunction>
行Form.getPartsArray()
返回一个数组,但数组中的值为空。 (例如,FilePath:'',FileName:'')
这使我相信FormData
的行为方式与发布的实际形式不同,无论ajax是否将FormData
发布为multipart / form-data。
问题
- 为了检索FileName,我在ColdFusion端读取
FormData
对象时缺少什么。 - 表格范围如何有效地利用张贴的
FormData
,就好像它是一个真正的<form>
被张贴。
研究
这个source表示我可以使用Java的FileOutputStream读取该文件。 (不是理想的解决方案,因为我也允许使用已经使用表格范围的典型“选择文件”)
我找到了一个解决方案,虽然不是我最初希望的解决方案。
根据我的观察,ColdFusion不会像对待实际的表格一样对待FormData
对象。当表单范围不包含表单数据时,这一点很明显。
相反,我必须以不同的方式处理使用拖放功能发布的数据。
按照建议的上传文件块的方法(source),我通过ajax请求upload.cfm
页面,其中Content-Type匹配要上载的文件的MimeType,实际上传使用java.io.FileOutputStream
类将文件写入磁盘。
javascript + AJAX:
var droppedFiles; // Assuming droppedFiles was populated during the 'drop' event
// Get the Form and FormData (although FormData won't be used when files are Dragged & Dropped)
var $form = $('.file-upload-container');
var ajaxData = new FormData($(form).get(0));
var dragged = false;
var filesToBeUploaded = document.getElementById("attachment");
var file = filesToBeUploaded.files[0];
if (droppedFiles){file = droppedFiles;dragged=true;}
$.ajax({
url: $form.attr('action'),
type: $form.attr('method'),
cache: false,
contentType: dragged ? file.type : false,
processData: false,
success: function(data) {
if (data.SUCCESS) { // Do stuff }
else
{
// Do stuff
console.error(data.ERROR);
}
},
error: function(jqXHR, textStatus, errorThrown) {
console.error('Error: File upload unsuccessful ' + errorThrown);
},
data: dragged ? file : ajaxData,
dataType: 'json',
dataFilter: function(data, type){
return data.substring(2, data.length);
},
headers: { 'X_FILE_NAME': dragged ? file.name : "", 'X_CONTENT_TYPE': dragged ? file.type : "" }
});
ColdFusion的:
<cfset bUseFormData = false />
<cfset headerData = getHTTPRequestData().headers>
<cfif structKeyExists(headerData, "X_FILE_NAME") AND ("#headerData.X_FILE_NAME#" NEQ "")>
<cfset bUseFormData = true />
</cfif>
<cfif structKeyExists(form, "attachment") OR bUseFormData>
<cfif bUseFormData>
<cfset content = getHTTPRequestData().content>
<cfset filePath = "#Application.AdminUploadPath#" & "#headerData.X_CONTENT_TYPE#">
<cfset fos = createObject("java", "java.io.FileOutputStream").init(filePath, true)>
<cfset fos.write(content)>
<cfset fos.close()>
<cfelse>
<cffile action="UPLOAD" filefield="form.attachment" destination="#Application.AdminUploadPath#">
</cfif>
</cfif>
为简单起见,我排除了验证文件扩展名,MimeType和错误处理的代码。
以上是关于ColdFusion无法读取Ajax发送的FormData的主要内容,如果未能解决你的问题,请参考以下文章
FORM HELP - 获取 PHP 脚本以通过 ajax 发送电子邮件数据
PHP 不读取 ajax 调用发送的 textarea 内容