I'm trying to send file using jquery ajax method, and I don't know how to receive it in Coldfusion, convert it in proper file object, and finally, save it on server in Media folder.
There is something I want:
var myDocument = $('#fileinput').prop('files');
var formData = new FormData();
formData.append('myDocument', myDocument);
$.ajax({
url: "./somePath/file.cfc?method=handleDocument",
type: "POST",
data: formData,
contentType: false,
processData: false,
success: function(result,status,xhr){
doSomething();
},
error: function(xhr,status,error){
doSomethingElse();
}
});
Now, we are in ./somePath/file.cfc trying to fetch myDocument object and save it:
<cffunction name="handleDocument" access="remote" returnformat="JSON" returntype="string">
<cfset requestData = GetHttpRequestData()>
<cfset content = requestData.content>
<cfset anyExtesion= content.getExtension()>
<!---There's no such method getExtension(), but I need something like that--->
<cffile action="write" file="./Media/myDocument.#anyExtesion#" output="#x.content#"/>
<cfreturn "File is saved in Media folder.">
</cffunction>
It's not necessary to manually parse the raw http request data to extract the file information. CFFile handles it for you:
Single file: cffile action="upload" and FileUpload() **
Multiple files: cffile action="uploadAll" and FileUploadAll() **
** The term 'upload' in the tag/function names is a misnomer. They handle low level i/o tasks for files already uploaded to the server
Single file uploads require the name of the form field containing the file to be uploaded. To avoid hard-coding a static value, make it an argument
to the cffunction instead. Use the result
variable to return details about the uploaded file as a structure (See CFFile - Usage Section for a list of the available properties).
Here's a starter example that allows uploading of a .PNG or .JPG file (any other extension throws an exception). A status structure is returned as json, if successful.
<cfcomponent>
<cffunction name="handleDocument" access="remote" returnformat="JSON" output="false">
<cfargument name="fileFieldName" type="string" required="true">
<!--- demo - only allow JPG files --->
<cffile action="upload"
destination="c:/nonwebaccessbile/path"
fileField="#arguments.fileFieldName#"
nameconflict="MakeUnique"
strict="true"
result="local.result"
allowedExtensions=".png,.jpg"
>
<!--- for demo return saved file name --->
<cfreturn {
"fileWasSaved": local.result.fileWasSaved
, "serverFile": local.result.serverFile
} >
</cffunction>
</cfcomponent>
var myDocument = $('#fileinput').prop('files');
One correction to the js code. The above returns a FileList object, not a file. To access the first File in the list, use $('#fileinput').prop('files')[0]
instead.
Then since the cffunction requires a field name, append that value to the FormData object before the ajax call:
var theFileField = $("#fileinput");
var theFieldName = theFileField.prop("name")
var theFirstFile = theFileField.prop("files")[0];
var formData = new FormData();
formData.append('fileFieldName', theFieldName);
formData.append(theFieldName, theFirstFile);
$.ajax({
url: "./pathto/file.cfc?method=handleDocument",
type: "POST",
data: formData,
dataType: "json",
contentType: false,
processData: false
}).done(function(response, status, xhr){
// do stuff here ...
}).fail(function(xhr,status,error){
// do stuff here ...
});
File uploads can pose a BIG security risk to web apps. Before putting ANY file uploads into production, read up on how to secure them first. A few good resources: