Mach II Properties in an AJAX request

43 views
Skip to first unread message

Jordan G.

unread,
Oct 20, 2009, 1:00:16 PM10/20/09
to Mach-II for CFML
Hi,

I'm trying to implement AJAX functionality through my M2 application
but I'm having some issues with it.

Right now, I have an Application.cfc that defines the M2 application
and a SessionFacade that is a property to the M2 application. The
SessionFacade.cfc manages all of the session information, similar to
the way that Adrian Moreno recommends. There is an
applicationProxy.cfc that extends the application in the webroot, and
then a directory called remoteFacades. The app.cfc in the
remoteFacades directory looks like this:

<cfcomponent extends="txwas.ApplicationProxy">

<cffunction name="onRequestEnd" access="public" returntype="void">
<cfsetting showdebugoutput="false" />

<cfscript>
Super.onRequestEnd();
</cfscript>
</cffunction>

</cfcomponent>

Then I have an ajaxProxy.cfc in that directory. The code runs
correctly as long as the Session scope is accessed directly, however
when I try to access the M2 Session Facade it crashes. This is the
code that is crashing:

local.argumentCollection.ROLE_ID = getProperty
("SessionFacade").getRoleID();

Says that getProperty isn't defined.

However, when I try to see if getProperty is available in the
remoteFacade directory's app.cfc, I get this error:

Error Occurred While Processing Request
Variable APPLICATION is undefined.

The error occurred in D:\inetpub\wwwroot\MachII\mach-ii.cfc: line 197
Called from D:\inetpub\wwwroot\MachII\mach-ii.cfc: line 186
Called from D:\inetpub\wwwroot\TXWas\remoteFacades\Application.cfc:
line 3

195 : hint="Get the Mach-II AppManager. Not available until
loadFramework has been called.">
196 : <cftry>
197 : <cfreturn application[getAppKey()].appLoader.getAppManager() /
>
198 : <cfcatch type="application">
199 : <cfthrow type="MachII.framework.AppManagerNotAvailable"

Am I doing something wrong here or should I just access the session
scope directly?

Thanks,

Jordan

Darren Walker

unread,
Oct 20, 2009, 3:39:55 PM10/20/09
to mach-ii-for...@googlegroups.com
Hi Jordan

Ignoring the question of Session facades etc, I've come across this kind of error before trying to do similar ajaxy stuff. 

Obviously the "getProperty isn't defined" error implies that the framework isn't loaded or is not loading properly.

The "variable APPLICATION is undefined" implies that the application scope hasn't loaded or is having a problem before it can.

How are you making your remote calls? via the usual http://domain/foo/index.cfm?event=bar ?

Or are you using cfajaxproxy or some such to call your ajaxProxy.cfc directly - if so you have to note that the mach-ii app will be bypassed, hence the errors.

It's hard to tell without seeing more code.

Cheers

Darren

Peter J. Farrell

unread,
Oct 20, 2009, 5:13:24 PM10/20/09
to mach-ii-for...@googlegroups.com
Sounds like your Application.cfc being used in the AJAX proxy directory is not inheriting from your Application.cfc in which Mach-II is being loaded.  That kind of error signifies that no application properties (at the top of your Application.cfc) have been defined.  You could be able to do a <cfdump var="#application#"/>  in your onRequestStart() method.  Any reason why you're using onRequestEnd instead?  The Mach-II bootstrapper uses onRequestStart() by default.

Sharing some additional code would be helpful.

.pjf

Darren Walker said the following on 10/20/2009 02:39 PM:

Jordan Gouger

unread,
Oct 20, 2009, 5:58:24 PM10/20/09
to mach-ii-for...@googlegroups.com

I think that is what is happening. What is really odd is that when cfdump is run in the app.cfc in the remote directory, it has full access to the application and even sees the M2 methods. It just crashes whenever it tries to read from the getProperty method.

 

I’m using the onRequestEnd in the remote directory to turn off debugging, and to call the main onRequestEnd in the main app.cfc to run some auditing processes. I can include all of the code if that would help?

 

Jordan

 

From: mach-ii-for...@googlegroups.com [mailto:mach-ii-for...@googlegroups.com] On Behalf Of Peter J. Farrell
Sent: Tuesday, October 20, 2009 4:13 PM
To: mach-ii-for...@googlegroups.com
Subject: [Mach-II] Re: Mach II Properties in an AJAX request

 

Sounds like your Application.cfc being used in the AJAX proxy directory is not inheriting from your Application.cfc in which Mach-II is being loaded.  That kind of error signifies that no application properties (at the top of your Application.cfc) have been defined.  You could be able to do a <cfdump var="#application#"/>  in your onRequestStart() method.  Any reason why you're using onRequestEnd instead?  The Mach-II bootstrapper uses onRequestStart() by default.

Sharing some additional code would be helpful.

..pjf



 

No virus found in this incoming message.
Checked by AVG - www.avg.com
Version: 8.5.422 / Virus Database: 270.14.22/2446 - Release Date: 10/20/09 10:43:00

Dave Evartt

unread,
Oct 20, 2009, 7:50:44 PM10/20/09
to mach-ii-for...@googlegroups.com
I ran into this same problem a few months back. Tried a number of
solutions, I was using the cfajaxproxy way of doing things, mostly
because I didn't want to mess with writing my own raw ajax methods.

I have since discovered jQuery and one of the firt thing I discovered is
that the jQuery ajax calls behave the way I expected thm to, meaning
that they are fully mach_ii compliant. I have since switched over to
jQuery and have had no further issues with ajax and mach_ii.

One caveat; If you turn logging on, you'll have to abort function calls
to prevent the logging functions from returning with the data. I've been
thinking about putting a test in a plugin, looking for ajax calls( I use
'ajax.' in the event names and just do a CFABORT in the plugin when it
sees an ajax call. Haven't tried it yet but it should work. It's cleaner
than putting cfaborts in the gateways and listeners.

I recommend dumping the cfajaxproxy methods from jQuery. It's cleaner
and much, much more robust.

Anyway, if you're doing ajax in mach_ii, I highly recommend jQuery. It's
made my ife a lot easier.

full disclosure: I am involved in no way with anyone associated with
jQuery development, I just happen to like it.

Cheers,

Dave Evartt

Jordan Gouger wrote:
>
> I think that is what is happening. What is really odd is that when
> cfdump is run in the app.cfc in the remote directory, it has full
> access to the application and even sees the M2 methods. It just
> crashes whenever it tries to read from the getProperty method.
>
>
>
> I’m using the onRequestEnd in the remote directory to turn off
> debugging, and to call the main onRequestEnd in the main app.cfc to
> run some auditing processes. I can include all of the code if that
> would help?
>
>
>
> Jordan
>
>
>
> *From:* mach-ii-for...@googlegroups.com
> [mailto:mach-ii-for...@googlegroups.com] *On Behalf Of *Peter
> J. Farrell
> *Sent:* Tuesday, October 20, 2009 4:13 PM
> *To:* mach-ii-for...@googlegroups.com
> *Subject:* [Mach-II] Re: Mach II Properties in an AJAX request

Jordan Gouger

unread,
Oct 21, 2009, 9:23:55 AM10/21/09
to mach-ii-for...@googlegroups.com
Thanks Dave. I'm using jQuery as it is now. I'm going to try using the ajax in the M2 events and see if that will fix the problem. Granted that is the easiest way, it violates every architecture article I've ever read to use AJAX with M2.

Jordan
Version: 8.5.422 / Virus Database: 270.14.22/2446 - Release Date: 10/20/09 18:42:00


Dave Evartt

unread,
Oct 21, 2009, 4:32:23 PM10/21/09
to mach-ii-for...@googlegroups.com
heres the code I added to my application plugin

<cffunction name="postProcess" access="public" returntype="void"
output="false">
<cfargument name="eventContext"
type="MachII.framework.EventContext" required="true" />
<!--- Handle ajax calls by killing the event after it has been displayed
--->
<cfset var event = arguments.eventContext.getCurrentEvent()>
<cfif left(Lcase(event.getName()),5) is "ajax.">
<cfabort>
</cfif>

<!--- <cfoutput>&nbsp;SimplePlugin.postProcess()<br /></cfoutput>
---> </cffunction>

I tried this out today and it works fine.

I'm not convinced that using ajax with M2 has a down side, especially
with jQuery. I don't want to step on any toes, but saying that ajax and
M2 don't mix is like saying firefox and m2 don't mix. What'sone got to
do with the other?

Making M2 calls via ajax (jQuery implementation at least) just makes
good sense, since all of the session scope is maintained and M2 doesn't
care (at least it shouldn't any more than it cares what OS was being
used, or what browser was being used) where the event came from, as long
as the application server (coldfusion) is happy with it.

Granted that there are security concerns with hidden calls to the
application, but really, are they really any less secure than the same
call from a browser link. I think not. but it's about the user
experience, and if we're not concerned with that then we can just say,
'no javascript, no java, no cookies, and nothing but plain old text'.
But since few developers fall into the Luddite category, and ajax really
has nothing to do with the M2 architecture anyway. I wouldn't think
twice about it.

In fact, using 'ajax.' prefixes in event handlers improves security
because the application can always be aware that it's an ajax event and
handle it any way it wants to. In fact, that's what I do in the
application plugin. I change the behavior of M2 for ajax calls as our
requirements dictate.

Now if you're dealing with back button issues, ajax presents problems,
but M2 is no more likely to have problems with it than any other web
based environment so you might as well say ajax has no place in the
universe. Since I don't believe that for a second, I'm going to move
forward with the rest of the industry, hopefully just a teeny bit faster.

When it comes down to it, making an ajax call should never be treated
any differently than any other call from the browser, regardless of the
platform the application runs under, since it is always under the
direct control of the browser anyway.


All of this is of course, just my opinion. your mileage may differ.


--

Peter J. Farrell

unread,
Oct 21, 2009, 5:50:55 PM10/21/09
to mach-ii-for...@googlegroups.com
Dave Evartt said the following on 10/21/2009 03:32 PM:

> Granted that there are security concerns with hidden calls to the
> application, but really, are they really any less secure than the same
> call from a browser link. I think not. but it's about the user
> experience, and if we're not concerned with that then we can just say,
> 'no javascript, no java, no cookies, and nothing but plain old text'.
> But since few developers fall into the Luddite category, and ajax really
> has nothing to do with the M2 architecture anyway. I wouldn't think
> twice about it.
>
Actually, this is a good point. Most people already have implemented
some sort of login / security process via filters or plugins in
Mach-II. If you run your AJAX outside of Mach-II, you have to re-create
those security measures again which lead to two implementations that are
trying to solve the same thing. Running AJAX through Mach-II means you
can leverage your already existing infrastructure. Having two
implementations is a security concern if one works slightly different
than the other.

Just curious why you abort your AJAX events in your example code? If it
has to do with Mach-II debugging output, you can programmatically turn
that off on an event by event basis (see the doco for the event-arg you
need to set).


> When it comes down to it, making an ajax call should never be treated
> any differently than any other call from the browser, regardless of the
> platform the application runs under, since it is always under the
> direct control of the browser anyway.
>

I totally agree normal browser requests and AJAX requests are just plain
old HTTP calls. It's just that AJAX is inside the user agent already so
it's probably going to do more stuff. They both of be secured the same way.

You can do some additional security because most AJAX libraries some
additional information in the user agent string and/or HTTP request
headers that identify it as an AJAX request. You could easily write a
plugin that looks for this information for AJAX events in Mach-II. This
would disallow the casual person from requesting that even via the
browser url -- however it's no replacement for true security in case
somebody spoofs headers / data via some other mechanism.


> All of this is of course, just my opinion. your mileage may differ.
>

Jordan, I'm curious where you read AJAX through Mach-II is bad. I think
is the past a few people have vocalize that they thought this might be
bad, but I've never been very convinced due to the lack of reasons. Bad
for bad sake isn't true reason to me. I guess Team Mach-II has never
really said otherwise to use AJAX in Mach-II, but from what we've talked
about for future versions of the framework -- AJAX integration / hooks /
tools for you to use will be expanded (my arm is being twisted a bit by
former team member Kyle Hayes to use DOJO -- he just wrote a book on
DOJO and I must admit people are over looking that framework).

Best,
.Peter

Dave Evartt

unread,
Oct 21, 2009, 6:06:07 PM10/21/09
to mach-ii-for...@googlegroups.com
Peter,

just out of curiosity, can you point me to the documentation about
turning off the loggining on an event by event basis? I did the plugin
thing because I didn't see a simpler way.

-dave

Peter J. Farrell

unread,
Oct 21, 2009, 8:14:51 PM10/21/09
to mach-ii-for...@googlegroups.com
FYI:

http://greatbiztoolsllc.trac.cvsdude.com/mach-ii/wiki/IntroToLogging#MachIILogger

Use the <event-arg name="suppressDebug" value="true"/> in your event-handler.

In future versions of Mach-II, we are planning on making AJAX requests automatically turn off any debugging output, but for now you'll have to use the event-arg in your event-handler.

.Peter

Dave Evartt said the following on 10/21/2009 05:06 PM:

Jordan Gouger

unread,
Oct 22, 2009, 6:33:26 PM10/22/09
to mach-ii-for...@googlegroups.com
Peter,

This is the article that I'm referring to: http://www.briankotek.com/blog/index.cfm/2007/7/25/AJAX-Data-Requests-vs-AJAX-Content-Requests

I agree with what he is saying, because essentially, what I'm trying to accomplish is an AJAX data request, not a content UI request. While this application isn't going the FLEX route now, it is conceivable that later in the future it might. Obviously if that ever happens, then I will rewrite the authentication into a SSO that powers a WSDL.

Jordan

-----Original Message-----
From: mach-ii-for...@googlegroups.com [mailto:mach-ii-for...@googlegroups.com] On Behalf Of Peter J. Farrell
Sent: Wednesday, October 21, 2009 4:51 PM
To: mach-ii-for...@googlegroups.com
Subject: [Mach-II] Re: Mach II Properties in an AJAX request


..Peter


No virus found in this incoming message.
Checked by AVG - www.avg.com
Version: 8.5.423 / Virus Database: 270.14.22/2446 - Release Date: 10/20/09 18:42:00


Dave Evartt

unread,
Oct 22, 2009, 8:41:28 PM10/22/09
to mach-ii-for...@googlegroups.com
Well,

I for one disagree with the basic premise that ajax calls for data
should not go through M2 but UI content should.

I am a firm believer in letting the framework do what it does so well,
and that's 'controlling' the application. Because there is no
substantial reason to treat one kind of browser call any differently
than another browser call, in addition to Peter's observation about the
duplication of security functions, necessitated by stepping out of the
M2 environment, simplicity just makes the application easier to develop
and maintain.

Now having said all that, there is a huge difference between using the
cfajaxproxy methods included with CF8 and using the much more robust and
flexible functions available the jQuery. I've been using the CF8 ajax
functions for the last couple of years and while they are handy for
people who only dabble with ajax, they are poorly suited for enterprise
level use. jQuery is a whole different world and my experience with it
is that it took me less to to become proficient with jQuery than it took
to figure out how to make the 'simpler' CF8 function perform the way I
wanted them to.

When that article came out (2007), it might have made sense, I've only
been on M2 for a couple of years. Considering how little understood
ajax, and the CF8 implementation of it, where at the time, it might have
born up. But that was then and this is now.

I remember when using a PC was considered a waste of time (yes that
dates me and my 34 years of computer programming) but just think how
that sentiment would hold up today. One of the things I've learned over
those long , hair pulling years, is that anything that makes my life
easier, the more I like it. On the other hand, I must be doing something
right from time to time; I'm still doing it 12-14 hours a day.

I for one think that the CF ajax functions should only be used by people
who can't do javascript. For those who can, it's so much easier and
friendly to use jQuery that it's a lot like the difference between
driving a Chevy and a Porsche. They'll both get you where you're going,
but wouldn't you really like to enjoy the ride?

It's just that for experienced programmers, CF ajax gets in the way more
than it helps. Again, my opinion...
-dave

Jordan Gouger

unread,
Oct 23, 2009, 9:21:54 AM10/23/09
to mach-ii-for...@googlegroups.com
Dave,

I completely agree with you about using the CF8 AJAX components. Not only are they not XHTML strict compatible, but they cannot be customized properly. Hence it is much better to use either jQuery or Ext JS directly. The same can also be said about using CF Form validation. Anyways I am going to try to integrate my AJAX data calls into the M2 framework and see how that works out. That is probably going to be the best usage of time rather than banging my head against the wall some more until a better solution to this problem presents itself.
Version: 8.5.423 / Virus Database: 270.14.22/2446 - Release Date: 10/22/09 18:44:00


Dave Evartt

unread,
Oct 23, 2009, 4:26:12 PM10/23/09
to mach-ii-for...@googlegroups.com
Jordan,

All you really need to know is the .post , .load, and .get functions.
You can do a buildurl inside these calls
just like any other link. Here is a simple example of a jQuery load ;

|$("#results").load(||"<cfoutput>#buildUrl('eventname')#</cfoutput>"||,
||function||(data)|
||| ||{|
//deal with the error ( or do something
else with the data)||||||||
||| ||});|

The function at the end is a callback that you can use to check for
errors, but if the call returns normally, the element with the id of
'results', will get populated just like you would expect it to from a
normal get. It really doesn't get much easier than that. This is of
course just scratching the surface.


-dave
Reply all
Reply to author
Forward
0 new messages