Ben Nadel
On User Experience (UX) Design, JavaScript, ColdFusion, Node.js, Life, and Love.
I am the chief technical officer at InVision App, Inc - a prototyping and collaboration platform for designers, built by designers. I also rock out in JavaScript and ColdFusion 24x7.
Meanwhile on Twitter
Loading latest tweet...
Ben Nadel at RIA Unleashed (Nov. 2010) with: Bob Silverberg

Handling 404 Errors in ColdFusion (via IIS Throwing 404)

By Ben Nadel on
Tags: ColdFusion

Some one over on the CF-Talk list posted a question about handling 404 errors in ColdFusion without using any sort of ISAPI_REWRITE or MOD_REWRITE. This is the way I do it. It is not perfect, but it works pretty darn well for my small, personal site.

The code here is rather long, so I have posted it to snippets as well.

  • <!---
  •  
  • For this example, Let's assume that the URL was:
  •  
  • http://www.bennadel.com/go/prettyurl/
  •  
  • This will be used in my comments below.
  •  
  • --->
  •  
  •  
  •  
  • <!---
  • Check to see if this was due to a 404 error. We might be accessing
  • this page via the Application.cfc onError event.
  • --->
  • <cfif Find( "404;", CGI.query_string )>
  •  
  • <!---
  • This is a 404 error. Now we have to go about figuring out just
  • what the error was intending. Right now, the error string is in the
  • form of:
  •  
  • 404;http://www.bennadel.com:80/go/prettyurl/
  • --->
  •  
  • <!---
  • Get the incorrect URL from the query string (which IIS has
  • thrown). This should start with "404;". It might also contain
  • the port number (ex. :80) after the domain extension. We want
  • to strip those out. We also want to strip out the "www."
  • since it might not be there.
  • --->
  • <cfset strTargetUrl = LCase(
  • REReplace(
  • CGI.query_string,
  • "404;|:80|www\.",
  • "",
  • "ALL"
  • )
  • ) />
  •  
  • <!---
  • ASSERT: strTargetUrl should now be in the form of:
  • http://bennadel.com/go/prettyurl/
  • --->
  •  
  •  
  • <!---
  • Get the site url. We want to strip out any www from it. This
  • way the site url *should* be part of the string we found above
  • (where we also stripped out "www").
  •  
  • NOTE: My url is stored in a config object... but you can get that
  • value from anywhere (or even hard code it right here). It is
  • http://www.bennadel.com/
  • --->
  • <cfset strSiteUrl = LCase(
  • Replace(
  • APPLICATION.ServiceFactory.GetConfig().GetUrl(),
  • "www.",
  • "",
  • "ALL"
  • )
  • ) />
  •  
  • <!---
  • ASSERT: strSiteUrl should now be in the form of:
  • http://bennadel.com/
  • --->
  •  
  •  
  • <!---
  • Now that we have the target url and the site url, we want to
  • remove the site url from the target url so that we can isolate
  • the script name that was being accessed.
  • --->
  • <cfset strTargetUrl = Replace(
  • strTargetUrl,
  • strSiteUrl,
  • "",
  • "ONE"
  • ) />
  •  
  •  
  • <!---
  • ASSERT: At this point, the strTargetUrl should hold the suffix url that
  • was trying to be called. That is, the url of the page minus the site domain:
  •  
  • go/prettyurl/
  •  
  • CAUTION: At this point, the page may contain query params (..?foo=bar).
  • --->
  •  
  •  
  • <!---
  • Check to see if we have any query params. Since the 404 error
  • passes the entire script name AND query string into the CGI
  • query_string, we have to manually pull out the query string
  • values ourself.
  • --->
  • <cfif Find( "?", strTargetUrl )>
  •  
  • <!--- We have query string values. Get the query params. --->
  • <cfset strTargetQueryParams = ListRest(
  • strTargetUrl,
  • "?"
  • ) />
  •  
  • <!---
  • Now that we have the target query params, we can remove
  • them from the target page.
  • --->
  • <cfset strTargetUrl = ListGetAt( strTargetUrl, 1, "?" ) />
  •  
  • <cfelse>
  •  
  • <!--- There are no query params. Set a blank value. --->
  • <cfset strTargetQueryParams = "" />
  •  
  • </cfif>
  •  
  •  
  • <!---
  • Make sure all the slashes are web slashes. This should already
  • be the case, but this is a safe-guard.
  • --->
  • <cfset strTargetUrl = REReplace(
  • strTargetUrl,
  • "[\\/]+",
  • "/",
  • "ALL"
  • ) />
  •  
  • <!--- Strip out trailing or leading slashed. --->
  • <cfset strTargetUrl = REReplace(
  • strTargetUrl,
  • "^[\\/]+|[\\/]+$",
  • "",
  • "ALL"
  • ) />
  •  
  •  
  • <!---
  • We need to ge the target directory. Check to see if we are
  • attempting to hit a file or a directory in the target url.
  • --->
  • <cfif REFind( "\.[\w]+$", strTargetUrl )>
  •  
  • <!---
  • The target item ends in a file ext. This must be a file.
  • Get the base directory from the file name and remove the
  • ending slash.
  • --->
  • <cfset strTargetDirectory = REReplace(
  • GetDirectoryFromPath( strTargetUrl ),
  • "[\\/]+$",
  • "",
  • "ONE"
  • ) />
  •  
  • <!---
  • Get the target script name to be the target url. This
  • will have the directory AND file.
  • --->
  • <cfset strTargetScriptName = strTargetUrl />
  •  
  • <cfelse>
  •  
  • <!---
  • We are not attempting to access any file, just a directory.
  • Grab that directory as the target directory.
  • --->
  • <cfset strTargetDirectory = strTargetUrl />
  •  
  • <!---
  • Since we are pointing to a directory, just grab that as
  • the script name as well.
  • --->
  • <cfset strTargetScriptName = strTargetUrl />
  •  
  • </cfif>
  •  
  •  
  • <!---
  • ASSERT: At this point, we have both :
  • - target url
  • - target directory
  • - target query params
  •  
  • that were attempted to get called. The target url does
  • NOT have any leading or trailing slashes, but it might
  • have a file name.
  • --->
  •  
  •  
  • <!---
  • Not that we have all that stuff, we have to figure out
  • what all that means to us on the LOCAL setup. IE, what
  • the fake url map to in our framework. Let's test the
  • tartet url against some regular expressios.
  • --->
  • <cfsavecontent variable="strXmlRedirectExpressions">
  •  
  • <!---
  • In order to narrow down the regular expression that
  • we have to run, I am checking the first item in the
  • target url.
  • --->
  • <cfswitch expression="#LCase( ListFirst( strTargetUrl, '/' ) )#">
  •  
  • <!---
  • FOR THIS DEMO i am putting the XML here. In
  • reality, I am pulling in an xml file form
  • each section so that each section can fine
  • tune it's own redirection.
  •  
  • ex:
  • <cfinclude
  • template="content/go/_url_redirect.xml.cfm"
  • />
  •  
  • For the demo, I have included it in the proper case.
  • --->
  •  
  • <cfcase value="go">
  •  
  • <redirect
  • in="^go/ben-?nadel\b.*$"
  • out="go.bennadel"
  • />
  •  
  • <redirect
  • in="^go/pretty-?url\b.*$"
  • out="go.demo404"
  • />
  •  
  • <!---
  • Notice in this one how I am using a reg-exp
  • group reference.
  • --->
  • <redirect
  • in="^go/pretty-?url/([0-9]{4})/\b.*$"
  • out="go.demo404&search_year=\1"
  • />
  •  
  • </cfcase>
  •  
  • </cfswitch>
  •  
  •  
  • <!---
  • After the individual cases, I include a global 404
  • handler in case none of the others make it.
  • --->
  • <redirect
  • in=".+"
  • out="home.display"
  • />
  •  
  • </cfsavecontent>
  •  
  •  
  • <!--- Trim the value on the XML. --->
  • <cfset strXmlRedirectExpressions = Trim(
  • strXmlRedirectExpressions
  • ) />
  •  
  •  
  • <!---
  • Check to see if there is a pretty url redirect expression
  • list that we can use to test the target url.
  • --->
  • <cfif Len( strXmlRedirectExpressions )>
  •  
  • <!--- Parse the expressions into an xml document. --->
  • <cfset xmlRedirectExpressions = XmlParse(
  • "<redirects>" &
  • strXmlRedirectExpressions &
  • "</redirects>"
  • ) />
  •  
  • <!--- Get query string children. --->
  • <cfset xmlChildren = xmlRedirectExpressions.XmlRoot.XmlChildren />
  •  
  • <!--- Loop through expressions to see if any match. --->
  • <cfloop index="intChild" from="1" to="#ArrayLen( xmlChildren )#" step="1">
  •  
  • <!--- Get reference to this child's attributes. --->
  • <cfset objXmlAttributes = xmlChildren[ intChild ].XmlAttributes />
  •  
  • <!---
  • Check to see if we found a match. Use the regular
  • expression in our redirects XML and test it against
  • the target URL.
  • --->
  • <cfif REFind( objXmlAttributes.In, strTargetUrl )>
  •  
  • <!--- Get the mapped action (the OUT xml attribute). --->
  • <cfset strTargetAction = REReplace(
  • strTargetUrl,
  • objXmlAttributes.In,
  • objXmlAttributes.Out,
  • "ONE"
  • ) />
  •  
  • <!---
  • Check to see if we have any query params as part of
  • the target action string.
  • --->
  • <cfif Find( "&", strTargetAction )>
  •  
  • <!---
  • Add the query params to the target query params that
  • we got from the original 404 error url.
  • --->
  • <cfset strTargetQueryParams = ListAppend(
  • strTargetQueryParams,
  • ListRest( strTargetAction, "&" ),
  • "&"
  • ) />
  •  
  • <!---
  • Get rid of the query string part of the
  • target action since we just copied it
  • over to the target query params.
  • --->
  • <cfset strTargetAction = ListFirst(
  • strTargetAction,
  • "&"
  • ) />
  •  
  • </cfif>
  •  
  • <!---
  • We found a regular expression match to the
  • target URL. We don't need to keep searching
  • so break out of the loop.
  • --->
  • <cfbreak />
  •  
  • </cfif>
  •  
  • </cfloop>
  •  
  •  
  • <!---
  • ASSERT: At this point, we have the:
  •  
  • - target url
  • - the target query params
  • - mapped action (based on the reg-exp)
  • --->
  •  
  •  
  • <!---
  • Update script name based on the error. Since we cannot
  • update the CGI.script_name value directly, I am storing
  • the target "script name" in a custom variable.
  •  
  • I keep a struct called Environment (CFC), but this could
  • be any variable that you reference in the page processing.
  • --->
  • <cfset REQUEST.Environment.OverrideScriptName(
  • GetDirectoryFromPath( CGI.script_name ) &
  • strTargetScriptName
  • ) />
  •  
  •  
  • <!---
  • Remove the 404 error from the attributes. This is
  • custom struct in my framework that combines the
  • URL and FORM variables.
  • --->
  • <cfloop item="strKey" collection="#REQUEST.Attributes#">
  •  
  • <cfif NOT Compare( "404;", Left( strKey, 4 ) )>
  • <cfset StructDelete( REQUEST.Attributes, strKey ) />
  • </cfif>
  •  
  • </cfloop>
  •  
  •  
  • <!---
  • Now, we need to move any target query params into my
  • framework's attributes scope. Since I never reference
  • URL for FORM directly, I do NOT bother updating them
  • at this point, but you could certainly set URL values
  • here.
  • --->
  •  
  • <!--- Update the attribute values. Get the array of params. --->
  • <cfset arrQueryParams = ListToArray(
  • strTargetQueryParams,
  • "&"
  • ) />
  •  
  • <!---
  • Loop over the query param pairs and add them to the
  • request attributes scope.
  • --->
  • <cfloop index="intPair" from="1" to="#ArrayLen( arrQueryParams )#" step="1">
  •  
  • <!--- Get the pair. --->
  • <cfset arrPair = ListToArray( arrQueryParams[ intPair ], "=" ) />
  •  
  • <!--- Make sure we have two items. --->
  • <cfif (ArrayLen( arrPair ) NEQ 2)>
  • <cfset arrPair[2] = "" />
  • </cfif>
  •  
  • <!--- Set the attributes value. --->
  • <cfset REQUEST.Attributes[ arrPair[1] ] = arrPair[2] />
  •  
  • </cfloop>
  •  
  •  
  •  
  • <!---
  • THIS NEXT IF STATEMENT IS PART OF MY FRAMEWORK. I DO NOT USE
  • ABSOLUTE URLS IN MY APP. ALL MY URLS ARE RELATVE (IE. ../../../).
  • BECAUSE OF THIS, I NEED TO UPDATE WHAT THE SERVER THINGS THE
  • WEB BROWSER IS SEEING. SINCE THE SERVER IS IN THE ROOT AT
  • THIS PAGE (site_error.cfm) AND THE WEB BROWSER IS IN A SUB
  • DIRECTORY, THE TWO PATHS DO NOT LINE UP.
  •  
  • HOWEVER, DUE TO THE WAY MY 404 HANDLER WORKS ON DEV, I HAVE TO
  • DO THIS DIFFERENT ON THE DEV AND LIVE SERVERS.
  • --->
  •  
  • <!---
  • Check to see why we are on the site_error.cfm page. If we are,
  • then we were thrown directly to it (probably on the
  • developmental server). In this case, use the appropriate web
  • root (which would be ""). However, if we are not on that page,
  • then we probably go sent here from another page (probably on
  • the live server).
  • --->
  • <cfif APPLICATION.ServiceFactory.GetConfig().GetIsLive()>
  •  
  • <!--- We are live, get the webroot based on the query string. --->
  • <cfset REQUEST.Environment.Web.Root = RepeatString(
  • "../",
  • ListLen( strTargetDirectory, "/" )
  • ) />
  •  
  • </cfif>
  •  
  •  
  • <!--- We do, so set the header to be proper code. --->
  • <cfheader
  • statuscode="200"
  • statustext="OK"
  • />
  •  
  • <!--- Store the target action. --->
  • <cfset REQUEST.TargetAction = strTargetAction />
  •  
  • <!--- Include the index file. --->
  • <cfinclude template="index.cfm" />
  •  
  •  
  • <!---
  • We have just include the main site controller (index.cfm)
  • We DO NOT WANT the rest of this template execute.
  • --->
  • <cfexit />
  •  
  •  
  • <!---
  • There was no matching Regular Expression file for this
  • html. Therefore, we are going to state that this page
  • was reached in error.
  • --->
  • <cfelse>
  •  
  •  
  • <!--- If we are live. Send an email to alert error. --->
  • <cfif APPLICATION.ServiceFactory.GetConfig().GetIsLive()>
  •  
  • <cfmail
  • to=""
  • from=""
  • subject="Error Page Reached"
  • type="HTML">
  •  
  • #CGI.script_name#<br />
  • #CGI.query_string#<br />
  • <br />
  •  
  • <cfdump var="#CGI#" />
  • <cfdump var="#REQUEST#" />
  • </cfmail>
  •  
  • </cfif>
  •  
  •  
  • </cfif>
  •  
  •  
  • </cfif>
  •  
  •  
  • <!---
  • ASSERT: This page was reached in error. No 404 error was
  • mapped. Either someone has a bad link or they are
  • trying to hack my site!
  • --->
  •  
  •  
  • <!--- DISPLAY STANDARD HTML PAGE HERE. --->
  •  
  • <cfabort />



Reader Comments

Ben,
I have downloaded your example and it looks very straight forward. Thanks for the help on handling 404 errors. I am trying to implement this method now on a IIS5 / W2K box. I am having trouble getting IIS to call my error handling page.

Here is what I did. I took your snippet, created a new file, 404handler.cfm. I then went into IIS, went to the web site I am testing and changed the Customer Error 404 to my new 404handler.cfm.

Problem is, is that IIS is not sending my 404_handler.cfm to CF for processing, all I get on my page is the output I requested (I wanted to see the cgi variable you are parsing). So, question is, what did I do wrong in setting up my error 404 handler in IIS?

Thanks,
Dave Hatz

Reply to this Comment

Dave,

Bear with me and debugging this as IIS is not my speciality. I know that when you set up IIS to handle 404 errors, you have several options to choose from (ie. File, URL, and I think one other)... what did you choose?

Reply to this Comment

Dave,

This might sound sad, but right now, there is no one here who as access to IIS, so I can't check how we do it. I am pretty sure that we use URL:

/cferror.cfm

On the live server, this usually isn't a problem. On the local server (where we don't have individual sites set up in IIS), we have to modify it a bit:

http://www.bennadel.com/index.cfm?dax=blog:108.view

This puts the error handler in the root of the sever, which in turn catches the error and crawls up the directory looking for a local cferror.cfm.

Reply to this Comment

Ben,
You da man, that was it. Set the Error Template to type of URL and that did the trick.

Thank you very much for your help.

Dave Hatz

Reply to this Comment

This works on Windows 2000, but not on 2003. The posted values (form) are not passed to the 404 handler it seems..

Or is it just me?

Reply to this Comment

@Etienne,

I believe that I have seen it work on a 2003 server, but I am not sure. Are you getting some sort of error?

Reply to this Comment

Hi Ben,

Thanks for your reply.

There's one notable difference. On 2000, the error number when there is a form posted to a non exist file in 403. (Method not allowed). On 2003, it is the 404.

I ran the HTTP analyser to try to find a difference between both server but there isn't.

I made a test also just trying to get the form value, but they were not defined.

So it seem that the value are simply not passed.

But there must be a way ...

Reply to this Comment

@Etienne,

That is too weird. I find it hard to believe that the page-not-found error would have different numbers on different versions of a server. Those numbers are a global standard (I think) and their meaning is not server dependent... very odd.

Reply to this Comment

Hi Ben,

Yeah it's weird.. But on 2000, it's actualy not page not found, but "Method not allowed" (it's 405 - i wrote 403 in the previous post).

According to Adobe, there is 3 possible reasons, and those 2 are interesting...

- "The action attribute of a form does not point to an executable script or there is no file specified for the action (in which case, the action field in the Property inspector is blank)."

- "The form's action attribute points to an HTML file."

Maybe it's the second reason. So maybe it not allowed to post a form on a htm file on 2000, but allowed on 2003. And maybe 404 doesn't not pass form value and 405 does?

So if it was possible to make sure a 405 is flaged instead of 404 it would maybe work.! But i'm not sure it's possible to do that...

Reply to this Comment

@Etienne,

Interesting stuff. Yeah, I generally point my form actions to CFM pages. I figure form processing pages don't need to be search engine friendly.

Reply to this Comment

Hi Ben,

thanks for the brainstorm today.!

I've found it not possible anymore in 2003.

http://www.hostingforum.ca/3380-iis-6-form-post-data-missing-404-405-custom-error-handle.html

So I found a way to post forms on existing page instead.

ciao!

Reply to this Comment

To Dave and others who like the idea of instead just putting a CFML-based error handler into the IIS custom error handler for 404's, beware. That now takes control for filetypes other than just .cfm,meaning GIFs, JPGs, etc.. I saw one situation where a site had lots of missing files, and they used this technique to have the IIS 404 call a CFM, which did a CFLOCATION to a CFM page.

Well, under load, that was killer, because the missing file might just be a spacer.gif being loaded up in many places on a page. Multiple that by high load, and suddenly every page request (with img srcs tags trying to get this missing GIF) would now trigger the CFM error handler page, which in their case then redirected to a front page (also a CFM page). Since the spacers were set to 1x1, no one ever noticed this happening. Yikes.

Clearly, such an IIS-based custom 404 error handler written in CFML needs to to either be coded to handle only CFM, CFML, or CFC files, or you need to consider some other solution (such as Ben's original one). Dave's was a short-cut. Ben didn't have the IIS 404 error handler pointing to a CFM page.

One might propose to instead assign Dave's 404handler.cfm to the CF Admin "site-wide missing template handler", where at least it will apply only to files that are handed to CF by the web server. And in CF8, we also now have the new per-application missing template handler (where you can define an onMissingTemplate function in application.cfc).

Hope that helps someone.

Reply to this Comment

Charlie makes a good point. I have seen sites where people were including old CSS sheets and JS files that no longer existed and there were throwing "hidden" 404 errors on every single page request.

One thing you can be sure to do is that if you handle a 404 and decide that it's not a "Valid" 404, then log it in some way that you can see the requests that are triggering the error.

Reply to this Comment

Some background:
My 404 page contains cfincludes for header/footer files and also includes loads of variables/structures that are initialized in application.cfm.

This wouldn't regularly be an issue if IIS had "Check if files exists" on. But I've got "Check if file exists" in IIS off due to seo friendly urls. So any non .cfm/.cfml page that doesn't exist get's handed off perfectly by IIS/Coldfusion. But, if a .cfm/.cfml page doesn't exist for some odd reason the application.cfm page IS NOT INCLUDED.

The Workaround:
I had to add the following workaround to the very top of the 404.cfm page, it doesn't include application.cfm if it's called directly because it loads correctly, if it's called by coldfusion's missing template handler it does include it:

<cfif cgi.script_name neq "/404.cfm">
<cfinclude template="/application.cfm">
</cfif>

Where "/404.cfm" is your missing template handler. Maybe I'm missing something? or is this a bug? Either way I hope this helps someone.

Reply to this Comment

So clarify please... should I or should I not be using this example as my IIS 404 error handler? Is this page going to be hit for every 404 including missing images, etc.?

Reply to this Comment

@Connie,

I use a newer version of this technique for this blog and it has been working fantastically. I'm not quite happy with the implementation; but aside from some clean up, I've been very happy with this.

Reply to this Comment

@Connie,

Also, yes, this will be hit when images are missing as well. But, you can put logic in to send that to a standard 404.

Reply to this Comment

Has anyone come up with a fix for the problem with IIS under 2003 not including the form variables with the 404 redirect? This has been a problem for me since IIS 5. They do not seem to get passed to my custom error handler nor do they appear in any of the other CGI variables.

Reply to this Comment

Ben,

Do you have your "newer" version blogged about somewhere? Read your reply two-up. I'm looking for a working 404 handler for cfms and cfcs. I know you are onto modrewrite now, but we don't have that available.

Thanks!

Reply to this Comment

@Justin,

I've actually starting using a tiny bit of URL rewriting with IIS Mod-Rewrite. It's more or less the same kind of logic, but 404 errors get re-written to point to the front-controller (index.cfm) where the 404 can be full processed:

http://www.bennadel.com/blog/1696-Exploring-IIS-Mod-Rewrite-For-Rewriting-URLs-In-A-ColdFusion-Application.htm

... and here:

http://www.bennadel.com/blog/1701-Using-IIS-URL-Rewriting-And-Application-cfc-s-OnMissingTemplate-Event-Handler.htm

... and here:

http://www.bennadel.com/blog/1744-Using-IIS-URL-Rewriting-And-CGI-PATH_INFO-With-IIS-MOD-Rewrite.htm

The logic that I am using in production is more or less along these various lines. Basically, in the URL rewriting, I append the 404 url as a query string variable during the rewrite. Then, in the onRequestStart() event handler, I check the 404 query string variable for patterns and route as appropriate.

Reply to this Comment

Ben,

I read all those posts looking for an update. So, I just wanted to make sure that your comment above wasn't implying that you significantly changed this code for the better. By the way, the snippet doesn't work.

Cheers

Reply to this Comment

Just to be clear-clear. I don't need further support on this issue. However, the snippet link above doesn't work. It just keeps telling me to get back to the gym. However, it's so hard now with a kid and a house and a new hobby or two...and...and...and...

Reply to this Comment

@Justin,

Ha ha, I had not idea what you were talking about at first :) I haven't use the "Snippets" section in so long. I disables that part of the site a while back and totally forgot about it. I'll have to update the link.

As far as the error handling, yeah, the premise is almost exactly the same. The way I do it now is I rewrite 404 requests to something like

./index.cfm?404=(...original_request...)

Not exactly that, but that's the idea. Then, in my Application.cfc, I run pattern matching against the original request to figure out how I want to route it.

Same concept, but I think it's a bit cleaner.

Reply to this Comment

As always, Ben, great post! - Based on your example, I've been using something similar on our production servers for quite some time now.

Here goes my question for today :
- Does anyone know how to set up something similar on CF's built in web server in order to emulate the 'SEO friendly' url on a development environment ?

I've been looking into the SERVER-INF/default-web.xml config file :
<error-page>
<exception-type>java.io.FileNotFoundException</exception-type>
<location>/Default.cfm</location>
</error-page>

...with unexpected results, so far.

Reply to this Comment

<error-page>
<exception-type>java.io.FileNotFoundException</exception-type>
<location>/</location>
</error-page>

...in SERVER-INF/default-web.xml _seems_ to work !

Reply to this Comment

I'm still having an issue getting this 404 thing to work.

I've setup IIS 7 to use URL:
/errors/404-test.cfm as the 404 page handler.

This works great if someone were to request:
www.mitchellcc.edu/about.html (or .htm)

But our site has always been CF, and when you request:
www.mitchellcc.edu/about.cfm

You get the standard CF "File Not Found" template.

What am I missing here?

P.S. I can't use the site-wide handlers, because I have multiple sites with different designs on the same server using sub-domains.

Thanks.

Reply to this Comment

@David,

That's a normal CF behavior, you should set up an onMissingTemplate function in your application.cfc.

Reply to this Comment

@Gov, What if I'm still using <cringe> Application.cfm?

I've got a CFERROR tag for Requests and Exceptions. I thought the Request one would capture missing pages/templates?

Reply to this Comment

@David,

I was afraid you ask that question. I have no idea; may be we should ask Ben!

Ben! Where Art Thou? Please help!

Reply to this Comment

Hi there

I have a simple CF page set to do a dump of the server only at this stage.

<cfdump var="#server#">

It works fine when I'm on the server itself and run from 127.0.0.1/project-tracker/index.cfm

When I try to run from www.project-tracker.com.au - I get a 404 file or directory not found

Is this a CF error or is this an error being thrown up from IIS

Thanks in advance.

Kind regards

Reply to this Comment

Post A Comment

?
You — Get Out Of My Dreams, Get Into My Comments
Live in the Now
Oops!
Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.