Search code examples
jqueryajaxcoldfusioncffile

Coldfusion, jquery and sending a file using ajax


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>

Solution

  • It's not necessary to manually parse the raw http request data to extract the file information. CFFile handles it for you:

    cffile action="upload"

    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>
    

    JavaScript

    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 ... 
    });
    

    Security

    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: