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
Related
I am trying to put the filename of a failed upload into an email, inside a try / catch, but I am not having any luck.
Based on this documentation - FileUploadAll() - I decided I am going to use error.
<cftry>
<cffile destination="#FULLPATH#" action="upload" nameconflict="ERROR" continueOnError="true" filefield="FileName" />
<cfcatch type="Any" >
<cf_EmailHandler from="testmail#gmail.com" to="testmail#gmail.com" subject="Attachment Error - #BUILD_SEARCH.PROJECT_VERSION# #BUILD_SEARCH.BUILD_NUMBER#">
<CFOUTPUT>
Attachment Error - #BUILD_SEARCH.PROJECT_VERSION# #BUILD_SEARCH.BUILD_NUMBER#
Cannot upload the following file:
#FULLPATH# #ArrayLen(cffile.uploadAllErrors)#
</CFOUTPUT>
</cf_EmailHandler>
<b>Error:</b>File already exists.
<cfabort>
</cfcatch>
</cftry>
I get the following error:
Element UPLOADALLERRORS is undefined in CFFILE
So I try to fix that:
<cftry>
<cffile destination="#FULLPATH#" action="upload" nameconflict="ERROR" Errors="errorResult" continueOnError="true" filefield="FileName" />
<cfcatch type="Any" >
<cf_EmailHandler from="testmail#gmail.com" to="testmail#gmail.com" subject="Attachment Error - #BUILD_SEARCH.PROJECT_VERSION# #BUILD_SEARCH.BUILD_NUMBER#">
<CFOUTPUT>
Attachment Error - #BUILD_SEARCH.PROJECT_VERSION# #BUILD_SEARCH.BUILD_NUMBER#
Cannot upload the following file:
#FULLPATH# #ArrayLen(errorResult.uploadAllErrors)#
</CFOUTPUT>
</cf_EmailHandler>
<b>Error:</b>File already exists.
<cfabort>
</cfcatch>
</cftry>
Then I am getting:
Element UPLOADALLERRORS is undefined in ERRORRESULT.
Any idea on what I am doing wrong or another way to display the name of failed upload? Also I am using ColdFusion 11.
Update:
Bug report CF-4204290 currently lists this issue as "To Fix".
TL;DR;
It's a documentation bug. The continueOnError attribute isn't supported with action=upload. Use action=uploadAll instead. Keep in mind "uploadAll" supports multiple files, so results will be returned as an array of structures.
The reason it's not working is because the code is using the wrong "action". It should be action="uploadAll". Since you're using continueOnError="true", CF populates a structure with any errors that occur. By default it uses CFFILE, but you can specify a different variable name by using the errors attribute.
<cffile destination="c:/some/path/"
action="uploadAll"
nameconflict="ERROR"
continueOnError="true"
filefield="file_path" />
Update:
As pointed out in the comments, the documentation does saycontinueOnError is a supported attribute for action=upload. However, IMO it's a documentation bug. Adobe probably just copied the text from the action=uploadAll description.
Interestingly, the documentation for FileUpload(), doesn't list that attribute at all. Bug report CF-4199503 confirms the function version doesn't support it. Based on my tests below with CF11 and CF2016, I've concluded it's not supported in either version.
Test Action=UploadAll
Uploading a file that already exists in the destination directory, doesn't cause a hard error. CF populates the specified variable with error details and dumps them on screen:
<cfif structKeyExists(FORM, "submit")>
<cffile destination="c:/temp"
action="uploadAll"
nameconflict="ERROR"
continueOnError="true"
errors="myErrors"
filefield="file_path" />
<cfdump var="#cffile#" label="cffile">
<cfdump var="#myErrors#" label="errors">
</cfif>
<form method="POST"
enctype="multipart/form-data">
<input type="file" name="file_path">
<input type="submit" name="test">
</form>
Results:
Test Action=Upload
Change the action to action="upload" and the code fails. ColdFusion does NOT:
Continue processing after the error .. or
Populate cffile with error information ... or
Create a result variable named by the errors attribute
Results:
Note, omitting the optional errors attribute produces the same results. It works as expected when using action=uploadAll and fails with an error when using action=upload
In the form page, I captured the filename using JavaScript
<Input Name="FileName" type="file" size="#TEXT_AREA_WIDTH#"><br><br>
<Input type="Hidden" id="READ_FILE_NAME" name="READ_FILE_NAME" value="">
<Input type="Submit" name="Operation" value="Save" onclick="return validateAttachmentForm(this.form.FileName.value)">
function validateAttachmentForm(file_name)
{
if (file_name.lastIndexOf("\\" != -1)) {
var file_name = file_name.substring(file_name.lastIndexOf("\\") + 1, file_name.length);
}
document.getElementById("READ_FILE_NAME").value = file_name;
if(file_name != "")
{
return true;
} else{
alert('Please select a file to upload.')
return false;
}
}
In the next page, I just display the filname passed in
<cftry>
<cffile destination="#FULLPATH#" action="upload" nameconflict="ERROR" Errors="errorResult" continueOnError="true" filefield="FileName" />
<cfcatch type="Any" >
<cf_EmailHandler from="testmail#gmail.com" to="testmail#gmail.com" subject="Attachment Error - #BUILD_SEARCH.PROJECT_VERSION# #BUILD_SEARCH.BUILD_NUMBER#">
<CFOUTPUT>
Attachment Error - #BUILD_SEARCH.PROJECT_VERSION# #BUILD_SEARCH.BUILD_NUMBER#
Cannot upload the following file:
#FULLPATH#\#form.READ_FILE_NAME#
</CFOUTPUT>
</cf_EmailHandler>
<b>Error:</b>File already exists.
<cfabort>
</cfcatch>
</cftry>
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
I have a table with my directory folder which contains all of my .txt files. Now I want that all .txt files are readable. I know I have to use <cffile action="read" ...>, but always something went wrong. How do I integrate the cffile tag into my script?
<cfparam name="name" default="0">
<h3>cfdirectory-Test</h3>
<cfdirectory
directory = "#ExpandPath('150903T')#"
action= "list"
name = "meinVerzeichnis"
sort = "name ASC, Type DESC, dateLastModified, Size"
type = "all"
filter = "*#name#*"
>
<cftable border="2"
query="meinVerzeichnis"
htmltable
colheaders>
<cfcol
header="Name:"
text="#Name#">
<cfcol
header="Type:"
text="#Type#">
<cfcol
header="Größe:"
text="#Size#">
<cfcol
header="Letztes Modifikationsdatum:"
text="#dateLastModified#">
</cftable>
<form method="get" action="msuche.cfm">
<button type="submit">Zurück</button>
</form>
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.
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.