2

I am using JQuery Ajax to post a form to a cfc.

When an error occurs, such as a duplicate post being made, then the cfc checks this and does a simple redirect. Its like this:

<cfif rsDuplicate.RecordCount GT 0>
  <cflocation url="/items/new" addtoken="no">
</cfif>

When this error occurs, the redirect is going crazy and appears to send a URL to my browser which contains the HTML for an entire webpage i.e. its like this http://mysite/items/<!doctype html><html lang="en"><meta charset="utf-8">...

I can't understand why its doing this. I'm pretty certain it has something to do with me making the original call to the CFC through Ajax but if I'm asking the server to redirect me to a new page, surely it doesn't involve the client at all?

I have also included data-ajax="false" in my form tag because I read somewhere that this may help, but it hasn't. Any ideas?

volume one
  • 6,800
  • 13
  • 67
  • 146
  • 3
    I think the road to success is to take the cflocation tag out of the cfc. Have the function return something appropriate to the calling code and handle it from there. – Dan Bracuk Feb 07 '15 at 23:17
  • The CFC does more than just redirect, it also sets a session variable that stores an error message and displays it to the user on the redirect page. I wish I could understand why its failing – volume one Feb 07 '15 at 23:49
  • What happens when you send the same parameters without using ajax? – Dan Bracuk Feb 07 '15 at 23:53
  • 1
    I think it's doing what it's "supposed to do". You're not cflocating the calling page, you're cflocating the request (the ajax'd cfc), it's obeying, and returning the generated contents. Dan is right, return a status code that signifies an error and handle the redirect with javascript. The CFC can still "store" an error message. – Regular Jo Feb 08 '15 at 00:52
  • Yes I think I've understood it now. I tried some various attempts and saw in the Net tab of Firebug that the response from the CFC was a "302 Moved Temporarily" status, but the actual page wasn't changing in my browser – volume one Feb 08 '15 at 01:44
  • So, you are sending data via AJAX, bit when there is an error, you want to redirect the page that sent the data to another URL? That is not how you should be doing it. The idea behind using AJAX is so that you need not redirect after a result comes back. – Scott Stroz Feb 08 '15 at 15:57

1 Answers1

1

AJAX'd CFC's (and server side objects in any language) are treated very much like a standard browser request. Just because you don't see the output directly, doesn't change that the browser sends a normal request, and gets the data back.

For instance, as you are probably aware, your cfc's obey your application.cfc's rules and will include headers and footers just like a normal browser page request.

When your duplicate-check triggers and evaluates to true, the cfc is being cflocationed to the new url, that cflocation is not passed back to the ajax call to trigger it from there. Cold Fusion cannot help you do this.

I do something similar to this in a few of my applications, and what I do is I return a struct containing a status variable at the top level. It might look something like

<cfreturn {STATUS = 2, KEYCODE = "Duplicate entries found", DESTURL = "/err_dupes.cfm"}>

Now, in the jquery ajax handler, in the success portion (because the call still succeeded), you can do something like this..

....
if (ajaxObj.STATUS == 2) {
  alert(ajaxObj.keycode); // If you want to notify the user.
  window.location.replace(ajaxObj.DESTURL);
}
Regular Jo
  • 5,190
  • 3
  • 25
  • 47
  • This is great. I basically copied this solution but did the return slightly differently. I'm doing this instead which I hope is ok: ` /path/to/redirect/page ` and then in my `success` function I do this `success function(result){ window.location.replace(result);}`. So just to explain, I'm outputing the URL for the redirect back to the Ajax calling page which is just using that raw string to do a javascript redirect. – volume one Feb 08 '15 at 01:52
  • @Volumeone Well, there's no reason to do the cfcontent bit, even if you want to do it that way... `` accomplishes exactly the same thing. – Regular Jo Feb 08 '15 at 01:58
  • I just tried it with a `` instead and it returns this to the browser address bar: `
    /path/to/redirect
    ` which causes it to crash with a 404
    – volume one Feb 08 '15 at 10:25
  • 3
    Why would you redirect the user after the AJAX is returned? That kind of defeats the purpose of using AJAX. You already know what the problem is and what the error message is. Include the error message in the JSON that is returned and then simply display the message on the same page as the form instead of redirecting. Otherwise, it is just like submitting the form data through a normal POST. – Scott Stroz Feb 08 '15 at 15:59
  • I suppose this whole thing came about from trying to make a traditional form into an ajax-ified form because I started using contenteditable divs which had to be submitted by ajax. Hence the backend was still treating everything as a traditional form. However, I am redirecting after the result is returned from the server because the on a successful insert the user has to be taken to the results page to see where their item was inserted – volume one Feb 08 '15 at 17:23
  • @volumeone On the `cfreturn` bit, does your cffunction specify a `returnformat`? Try setting to `returnformat="json". Also, you can use your cfc to return that information directly to the page but you're clearly learning as you go (no offense) but yes, Scott is right, you can engineer your application to just present the data which, done right, creates a better experience. – Regular Jo Feb 08 '15 at 17:36
  • 1
    You are submitting the data via AJAX, and then redirecting them even when it is successful? My question then would be, why bother using AJAX at all? You are adding an extra step for no reason. – Scott Stroz Feb 08 '15 at 18:43
  • @ScottStroz I just said, the form HAS to be submitted by ajax because its using html5 contenteditable divs that need to be serialized and sent by javascript. They're not form inputs. – volume one Feb 08 '15 at 21:13
  • 1
    Content editable divs do not need to be submitted via AJAX. - as noted here - http://stackoverflow.com/questions/6247702/using-html5-how-do-i-use-contenteditable-fields-in-a-form-submission You are just choosing to submit via AJAX. The way you are redirecting after receiving the response form the server is just wrong. – Scott Stroz Feb 08 '15 at 22:03
  • @cfqueryparam I have changed the cffunction to returnformat="JSON" but I get an odd output like `"products\/1\/volvo-xc90-t6"`. Any reason why? – volume one Feb 08 '15 at 23:27
  • @ScottStroz Can you please suggest a better way of letting a user submit an article or whatever via ajax() and then show the the result of their insertion which is on a different CFM page. How can it be done without a redirect? – volume one Feb 08 '15 at 23:28
  • 1
    You could return the data pertaining to the item and use a library like Angular to automatically display the content using bindings. – Scott Stroz Feb 08 '15 at 23:54
  • @volumeone Because special characters are escaped. Have no fear, it won't interfere with your script. I would guess that your string actually looks like `products/1/volvo-sc90-t6`? – Regular Jo Feb 08 '15 at 23:59