Skip to main content
Ben Nadel at the jQuery Conference 2011 (Cambridge, MA) with: Julian Aubourg
Ben Nadel at the jQuery Conference 2011 (Cambridge, MA) with: Julian Aubourg ( @jaubourg )

Throwing And Catching A File Using CFHttp For Both Actions

By on
Tags:

I can't remember where I heard this, but not so long ago I heard or read about someone who wanted to send a file to another server using CFHttp. He didn't have any FTP stuff set up, so that was they best idea he had. This seemed like a fun little piece of functionality to test as I have never done that before.

I set up two pages: cfhttp_throw.cfm and cfhttp_catch.cfm. As you can probably guess, the cfhttp_throw.cfm takes a file from the local file system and "posts" it to the cfhttp_catch.cfm. The cfhttp_catch.cfm file then "uploads" it to its server and echoes back the file name as it was stored on the new machine.

This was suprisingly easy. I have not used CFHttp all that extensively and in about 10 minutes I worked out something that did just what I wanted to do. And, in the process, I used a CFHttpParam tag of type "File" which I had never done before. I have to go back and check out the rest of the CFHttpParam types to see what else I am missing (damn you ignorance!).

Here is the cfhttp_throw.cfm code. It doesn't have all the CFTry / CFCatch tags that probably should be used, but for this proof of concept, it was not necessary:

<!---
	Submit the file the CFHTTP_Catch.cfm file. Notice that we
	are sending the file via a CFHttpParam FILE tag. By using
	this file param, CFHTTP automatically sends all form
	fields as multi-part form data; therefore, we do NOT need
	to specify the "multipart='true'" CFHttp attribute.
--->
<cfhttp
	url="http://swoop/..../cfhttp_catch.cfm"
	method="POST"
	useragent="Mozilla/5.0 Gecko/20070309 Firefox/2.0.0.3"
	result="objHTTP">

	<!---
		Send along a file via the FORM post. This acts the same
		as a stanard form Input type="file" field and can be
		handled as such on the "Catch" page.
	--->
	<cfhttpparam
		type="FILE"
		name="file"
		file="#ExpandPath( './test.jpg' )#"
		/>

</cfhttp>


<cfoutput>

	<h4>
		CFHttp Post Result:
	</h4>

	<p>
		#objHTTP.FileContent#
	</p>

</cfoutput>

And, here is the cfhttp_catch.cfm code:

<!--- Kill extra output. --->
<cfsilent>

	<!---
		Param the form fields. Since this data is coming via
		a CFHTTP "Post" we can operate as if it was a standard
		form submission.
	--->
	<cfparam
		name="FORM.file"
		type="string"
		default=""
		/>


	<!--- Try to upload the file. --->
	<cftry>

		<!---
			Upload the file. When defining the CFFile, we can
			treat the posted file as if it was submitted via a
			standard File Input (since it was posted as a FILE
			using CFHttpParam).
		--->
		<cffile
			action="UPLOAD"
			filefield="file"
			destination="#ExpandPath( './files/' )#"
			nameconflict="MAKEUNIQUE"
			/>


		<!---
			Echo back the name of the file as it has been
			saved to the server.
		--->
		<cfcontent
			type="text/plain"
			variable="#ToBinary( ToBase64( CFFILE.ServerFile ) )#"
			/>


		<!---
			Catch any errors that were thrown during the
			file upload.
		--->
		<cfcatch>

			<!--- Echo back the error message. --->
			<cfcontent
				type="text/plain"
				variable="#ToBinary( ToBase64( CFCATCH.Message ) )#"
				/>

		</cfcatch>
	</cftry>

</cfsilent>

That was pretty cool. I like that using the proper CFHttp / CFHttpParam tags, your target page can act as if the request was coming from a standard Form-action page with standard FORM-scoped values. I think it's totally awesome that CFFile can actually upload the file that is posted to it. Very cool.

Want to use code from this post? Check out the license.

Reader Comments

15,688 Comments

@Ray,

Cause I am a sick person .... the Variable attribute of CFContent only takes binary data and won't allow string data unless you convert it to binary first (hence the ToBinary stuff). Sure, I could just output it after the CFSilent, but I don't think that looks as nice.... Like I said, I am sick (in the head) and code formatting is that special to me :)

16 Comments

Hey Ben,

I've been playing around with drag-n-drop uploads using jQuery and XMLHttpRequest Level 2. Check out: http://onehub.com/blog/posts/designing-an-html5-drag-drop-file-uploader-using-sinatra-and-jquery-part-1

Basically it's a PUT method and not sure if this relates with exactly what you are doing here, but it seems to be somewhat the same.

I can get the PUT to work great, but I'm having problems with the "catcher" file, since obviously this is not using traditional form fields. Have you had any experience playing around with this yet?

16 Comments

@Ben

I think I answered my own question.

Looks like you can grab the XHR data using ColdFusions "GetHttpRequestData()" function. So to capture the file and save you would do something like this:

<cfset xhr_data = GetHttpRequestData() />
<cffile action="write" file="#ExpandPath('.')#/#CGI.HTTP_X_FILENAME#" output="#xhr_data.content#">

p.s. this doesn't work so well on older browsers.

16 Comments

@Ben,

Cool, I'll check it out.

The one I linked to above works in everything except IE. I've gotten it to work with the "PUT" method, but I'm struggling a little bit with the normal "POST" fallback option.

I'm sure I'll figure it out. Thanks.

15,688 Comments

@Doug,

If you have your stuff working in everything but IE, disregard my link. I believe the example in the link I sent you *only* works in the latest Firefox releases. Sounds like you are on a better track than me.

2 Comments

This is a good post! This is about sending a file with a http post request from Server A to Server B. I have a question about doing something slightly different.

what if server A wants to download a file from server B via an http request. so in essennce an http download. Is it something to do with what you set in cffilecontent response type? How nice it would be if there was a working example somewhere.

Thanks!

2 Comments

I guess i figured it out. I would need this on the httpResponse

<cfheader name="Content-Disposition" value="inline; filename=testing.doc">
<cfcontent type="application/msword" file="#fileName#" deletefile="no">

and something like this on the requester file.

<cfscript>
ioOutput = CreateObject("java","java.io.FileOutputStream");
ioOutput.init("C:\...\testing.doc");
objHTTP.Filecontent.writeTo(ioOutput);
ioOutput.close();
</cfscript>

I believe in love. I believe in compassion. I believe in human rights. I believe that we can afford to give more of these gifts to the world around us because it costs us nothing to be decent and kind and understanding. And, I want you to know that when you land on this site, you are accepted for who you are, no matter how you identify, what truths you live, or whatever kind of goofy shit makes you feel alive! Rock on with your bad self!
Ben Nadel