I've never used cffile upload. In looking at the documentation I see that the file to be uploaded is described as
Name of form field used to select the file.
Do not use number signs (#) to specify the field name.
I just cannot decipher this. If the file to be uploaded is john.jpg, residing on the user's disk, how do I indicate that in the cffile command?
I have other questions as well, but would like to start with this very basic one.
What documentation are you using? There should be an example like there is here: <cffile action="upload">
In this example (which I've edited), it shows that you do not reference the name of the file that the user selected, that could be anything, you reference the name of the form field, fileContents, that is used to upload the file.
<!--- Windows Example --->
<!--- Check to see if the Form variable exists. --->
<cfif structKeyExists(Form, "FileContents") >
<!--- If TRUE, upload the file. --->
<cffile action = "upload"
fileField = "FileContents"
destination = "c:\files\upload\"
accept = "text/html"
nameConflict = "MakeUnique">
<cfelse>
<!--- If FALSE, show the Form. --->
<form method="post" action=<cfoutput>#cgi.script_name#</cfoutput>
name="uploadForm" enctype="multipart/form-data">
<input name="FileContents" type="file">
<input name="submit" type="submit" value="Upload File">
</form>
</cfif>
Once the CFFILE process completes, a collection of variables are defined in a structure named CFFILE (see documentation link). One of these variables is cffile.clientFile, which contains the name of the file that was uploaded from the user's computer.
For the cffile command:
<cffile action = "upload"
fileField = "FileContents"
destination = "c:\files\upload\"
accept = "text/html"
nameConflict = "MakeUnique"
result = "thisResult">
...you would use #thisResult.clientFile# to get the original filename.
All the other fields would be available using this also.
I found this on stackoverflow:
ColdFusion ServerFile is undefined in CFFile
Related
I know how to upload an image file to a server and show the image file to a page.
But what if I want a preview on a confirmation page?
I can probably generate a temp file that isn't saved in the database but is a file in a physical location, but what if I decided to hit the "no" button. How would this temp file be deleted?
The code below shrinks the image and shows it on the page. But it also creates an image within the directory, that will stay there after I hit OK or NO. The NO is button, while the OK naturally is a submit.
<!--- Make Temp Image as Preview --->
<cfset mediapath = expandpath('../images/about')>
<cfif structKeyExists(form,"image") and len(form.image)>
<cffile action="upload"
filefield="image"
destination="#MediaPath#"
nameconflict="makeunique">
<cfimage name="uploadedImage"
source="#MediaPath#/#file.serverFile#" >
<cfset imagesize = 320>
<cfif uploadedImage.width gt uploadedImage.height>
<cfset percentage = (imagesize / uploadedImage.width)>
<cfelse>
<cfset percentage = (imagesize / uploadedImage.height)>
</cfif>
<cfset newWidth = round(uploadedImage.width * percentage)>
<cfset newHeight = round(uploadedImage.height * percentage)>
<!--- Show Image --->
<cfoutput>
<img src="../images/about/#file.serverFile#" style="height:#newHeight#; width:#newWidth#;">
I assume I may have to do URL Passing or do some sort of CFScript. On the Return buttons Onclick event.
Here is my approach take it for what you will.
Ok this is probably more than you need but this should get you somewhere on this image delete problem thing.
Here is your code. But I broke it into two pages. Of course I cannot see what else is going on this page and your form handling stuff so we will start with what you are giving us.
<cfset mediapath = expandpath('../images/about')>
nice use of structKeyExists() :)
<cfif structKeyExists(form,"image") and len(form.image)>
Here I would pause and suggest you limit
your uploads to just .gif, .jpeg, .jpg, .png
(your main image types) to prevent uploading any
and everyfile type. I added an accept parameter below.
<cffile action="upload"
filefield="image"
destination="#MediaPath#"
nameconflict="makeunique"
accept="image/*">
<cfimage name="uploadedImage"
source="#MediaPath#/#file.serverFile#" >
Ok the file is uploaded lets seperate concerns
At this point I would ask them if they want to preview the file. If they click 'preview' take them to a preview.cfm page.
Then you have a file name you need to pass if you have nothing else (like an ID or some primary key).
So I pulled this handy-dandy script out of the Adobe Coldfusion docs on their website and I am going to use this to turn your filename into 'something else' ;)
<cfscript>
theKey="123abc";
theKey=generateSecretKey("AES")
superDuperSecretSoDontTell=encrypt(file.serverFile, theKey, "AES", "hex");
</cfscript>
Let's send this piggy!
and off you go to the preview page...
<cfoutput>
(pointing up) This is pageA.cfm
(pointing down) This is pageB.cfm
Now I have the rest of your code below and lets pull your file based on the pass through querystring variable/value pairs.
<cfscript>
IWannaKnowTheSecret=decrypt(url.fileName, url.theKey, "AES", "hex");
</cfscript>
Here I would pause and suggest you limit
your uploads to just .gif, .jpeg, .jpg, .png
(your main image types) to prevent uploading any
and everyfile type. I added an accept parameter below.
<cffile action="read" file="#MediaPath##IWannaKnowTheSecret#" variable="uploadedImage">
<cfset imagesize = 320>
Interesting handle here. So you are taking the
larger of the two values and using that
to percentage down the size. Neat.
<cfif uploadedImage.width GT uploadedImage.height>
<cfset percentage = (imagesize / uploadedImage.width)>
<cfelse>
<cfset percentage = (imagesize / uploadedImage.height)>
</cfif>
<cfset newWidth = round(uploadedImage.width * percentage)>
<cfset newHeight = round(uploadedImage.height * percentage)>
Then do a form like this:
<form action="" method="post" enctype="multipart/form-data">
Your current Image:
<cfoutput>
Name: #uploadedImage#<br>
<img src="../images/about/#uploadedImage#" style="height:#newHeight#; width:#newWidth#;">
</cfoutput>
Do you want to remove this?<br>
<input type="checkbox"
name="removeImage"
value="1" />: Remove the logo image</cfif><br />
Wnat to replace your image?<br>
<input type="file" name="replacementImage"> (
<input type="hidden"
name="uploadedImage"
value="<cfoutput>#uploadedImage#</cfoutput>">
<input type="submit" value="submit" name="submit"
</form>
Cancel and go back
If they continue and want to fix the image or replace it. Submit then you can use something like this.
Then we delete...
And if the replacementImage file filed is populated then we add that file.
And there you have it...
You are seperating some concerns.
You are giving improved options.
You are allowing a change or no change.
You are giving them an out to go back to where ever you want.
Edit: Here is proof for the encoding and decoding stuff (if you wanted to play with it:
<cfscript>
theKey="123abc";
theKey=generateSecretKey("AES");
superDuperSecretSoDontTell=encrypt("monkeytoots", theKey, "AES", "hex");
</cfscript>
<cfoutput>Let's send this piggy!</cfoutput>
<cfif isdefined("url.fileName") and isdefined("url.theKey")>
<cfscript>
IWannaKnowTheSecret=decrypt(url.fileName, url.theKey, "AES", "hex");
</cfscript>
<cfoutput>
#IWannaKnowTheSecret#
</cfoutput>
</cfif>
This answer is in response to Adam Cameron's comment. It illustrates some potentially unexpected results that can occur with two submit buttons. Start with this code.
<cfdump var="#form#">
<form action="abc.cfm" method="post">
<input type="text" name="text1" />
<input type="submit" name="submit1" value="no" />
<input type="submit" name="submit2" value="yes" />
</form>
The default behaviour of most, if not all browsers is that there are occasions whereby a form will be submitted when the user presses the enter key. What would you expect to see with this form if you had your curser in the text box and pressed Enter? Try it and see if you were right.
I am trying to use this code for uploading files to my server but is giving me an error.
This is the code:
<cfif isdefined("form.submit")>
<cffile action="uploadall" destination="#expandpath('../../images/Uploads/after')#">
</cfif>
<cfform action="#cgi.script_name#" enctype="multipart/form-data">
<cfinput type="file" name="attachment1"><br>
<cfinput type="file" name="attachment2"><br>
<cfinput type="file" name="attachment3"><br>
<cfinput type="submit" name=" submit" value="submit">
</cfform>
This is the Error:
The following information is meant for the website developer for debugging purposes.
Error Occurred While Processing Request
Invalid content type: application/x-www-form-urlencoded.
The files upload action requires forms to use enctype="multipart/form-data".
The error occurred in E:\sites\Example.Com\testing\handlers\upload\after.cfm: line 20
I see that you've moved on to a different solution, but I wanted to answer your question because the answer is plain crazy (and is stereotypical of some of the bizarre gotchas in Coldfusion). The problem is that <cfform> simply doesn't support the enctype attribute. If you want to upload files, you have to use a plain <form>. Weird, right?
(I suppose you could change the XSLT so that a cfform with a file input results in the enctype being set correctly automatically. But why it doesn't do this out of the box is beyond me.)
Does the directory structure that you are referencing in the destination attribute exist '"#expandpath('../../images/Uploads/after')#"'?
If the destination attribute is not an absolute path then it is relative to ColdFusion's temp directory. Not relative to your web root or the template that is running.
Here is the description from the docs here
Pathname of directory in which to upload the file. If not an absolute path (starting with a drive letter and a colon, or a forward or backward slash), it is relative to the ColdFusion temporary directory, which is returned by the GetTempDirectory function.
I have a form that I would like to submit to a component for processing (CRUD behaviors), the problem is it seems passing multipart/form-data to a component somehow looses the file location. When it gets to the part of the component that should be uploading the file I get the infamous form field did not contain a file error.
I am not 100% sure why this happening but if I submit the form directly to a .cfm page that performs the cffile action everything works as expected, but if the .cfm page does something like:
<cfobject name="process_form" component="processor" />
<cfset result = process_form.upload( form ) />
and the component "processor" tries to do the upload, I get the form field did not contain a file.
My processor looks like:
<cfcomponent name="processor">
<cffunction name="upload" returntype="string">
<cfargument name="form_data" type="struct" />
<cffile action="upload" filefield="#arguments.form_data.file_1#" ...>
[ ... ]
</cffunction>
</cfcomponent>
One thing to note, is if I try use the variable arguments.form_data.file_1 without the # signs around it, I get the error:
The form field arguments.form_data.file_1 did not contain a file.
If I put the # signs around the variable I get:
The form field C:\JRun4\servers\cfusion\SERVER-INF\temp\cfusion-war-tmp\neotmp7350969777287007477.tmp did not contain a file.
Any idea on how to fix this issue? I would rather have all my processing actions inside a component, but right now I can't seem to make that work.
Thanks!
Will
You shouldn't need to use the full variable name when using a cffile tag--you just need the form field name, so something like:
<cffile action="upload" filefield="file_1" ...>
should suffice. The FORM struct field holds the location of the temporary file, but the cffile tag doesn't need that (I'd image that id directly accesses the FORM struct on the backend based on the fieldname you've provided).
cffile is giving a head ache now.
My cfm is like this -
`
<cfif session.ismac and session.browsermake eq "firefox">
<cfset size = "55">
</cfif>
<cfset onChange = "document.frmMain.submit1.disabled = true;setdisplayname(this,this.form.dummy);">
<cfif displayname EQ "">
<cfset size = "document.frmMain.submit1.disabled = true;setdisplayname(this,this.form.displayname);">
</cfif>
<cfinput type="file" name="File#thisUploader#" id="File#thisUploader#" size="#size#" onKeyPress="return false;" onchange="#onChange#">
`
and in my cfc the code is like this -
<cffile accept="image/*" action="upload" destination="#application.artworkfilepath#\bulkuploads\#session.loginname#\#form.category#\" filefield="form.File#thisUploader#" nameconflict="makeunique">
and if I dump - <cfoutput>
You uploaded #cffile.ClientFileName#.#cffile.ClientFileExt#
successfully to #cffile.ServerDirectory#.
</cfoutput>
<cfabort>
I get corrct things and no error.
But when i look into the folder there is nothing.
Anyidea? I have added the dump of cffile now. What do you make out of it?
cfform code is like this <cfform id="frmMain" name="frmMain" action="process_multi.cfm" enctype="multipart/form-data" target="_self" method="post">
do a fileExists() directly after the statement and let us know what that says...
you don't have a directorywatcher on the directory do you?
Your cffile nameconfict attribute is set to makeunique, which tells ColdFusion to rename the file to something new when it arrives at the server--if the file already exists.
However, you are using cffile.ClientFileName and cffile.ClientFileExt to refer to the file file--which maps to the unchanged file name as it was received during upload.
Change your code references to cffile.ServerFileName and cffile.ServerFileExt for the final renamed result.
I am using CF-8,windows-XP and IE 5.5.
I am using simple tag namely . but the output i am getting is pure gibberih along witht the text of the file(word document)
upld.cfm
<cffile action="read" file="C:\ColdFusion8\wwwroot\Proj\updl\fileDisk\SOL.doc" variable="fileDisk" >
<cfoutput>#fileDisk#
</cfoutput>
<cfoutput>
<form name="upload" method="post" action="actionUpld.cfm?form_Num=#form_Num#" enctype="multipart/form-data">
<input name="uplForm" id="uplForm" type="file" >
<input type="submit" name="submitUpld" value="Save" onclick="" >
</form>
</cfoutput>
actionUpld.cfm
<cftry>
<cfscript>
newUPL = CreateCFC('cfcs.projDB');
newUPL.Implementation_Num = url.form_Num;
newUPL.uplForm = form.uplForm;
newUPL.putUPL();
</cfscript>
<cfcatch type="any" >
<cfoutput >
<hr>
<h4>Other Error: #cfcatch.Type#</h4>
<li><b>Message:</b> #cfcatch.Message#
<li><b>Detail:</b> #cfcatch.Detail#
<li><b>Error Code:</b> #cfcatch.ErrorCode#
</cfoutput>
</cfcatch>
</cftry>
<cflocation url="upld.cfm??form_Num=#form_Num#" >
How best to use the cffile to output the file ?
Also when i look at the DB, i am getting the file name as
"C:\ColdFusion8\runtime\servers\coldfusion\SERVER-INF\temp\wwwroot-tmp\qeq344.tmp"
How to correct it?
Is there any better way.
Also when i look at the DB, i am
getting the file name as C:\ColdFusion8\runtime\servers\coldfusion\SERVER-INF\temp\wwwroot-tmp\qeq344.tmp
That is a temporary file name assigned to newly uploaded files. On your action page, you need to use cffile action="upload" ... to move that temporary file to the desired location. That will populate a structure called CFFILE with details about the uploaded file, such as CFFILE.serverFile and CFFILE.serverDirectory. (Or use the "result" attribute to output the details to whatever structure name you choose.)
How best to use the cffile to output
the file ?
You cannot display binary files (like *.doc) with cfoutput. To display/download such files in a browser use cfcontent