Link to home
Start Free TrialLog in
Avatar of irfantak
irfantak

asked on

CFHTTP REDIRECT FAILURE

Hi,
I have the following code which posts to another .CFM page. I can tell that correct page is being posted to (by looking at the CFDUMP which shows the posted Form data) but no redirect happens and no errors happen. Any idea?

-----------------
<cftry>
        <CFHTTP url="http://127.0.0.1:8082/MonkeyJoesCFM/reservation_intermediateTEMP.cfm" method="POST" redirect="yes">
<CFHTTPPARAM name="UserName" type="FORMFIELD" value="blah1">
<CFHTTPPARAM name="Password" type="FORMFIELD" value="blah2">
</CFHTTP>
<cfcatch type="any">
<cfoutput><cfdump var="#cfcatch#"></cfoutput>
</cfcatch>
</cftry>
------------------------------------------------
Avatar of gdemaria
gdemaria
Flag of United States of America image


what does it look like in reservation_intermediateTEMP.cfm ?


ColdFusion does the redirection only if it receives both a Location header AND a 300-series (redirection) status code.

(The cflocation tag does generate an HTTP 302 resonse with the url attribute as the Location header value.)
Avatar of irfantak
irfantak

ASKER

Thank you. Well, in order to troubleshoot, I have stripped out all HTML code (may not a good move?). Here is the code in the calling and caller pages.

----------------------------Calling Page-----------
        <cftry>
        <CFHTTP url="http://127.0.0.1:8082/MonkeyJoesCFM/reservation_intermediateTEMP.cfm" method="post" resolveurl="yes" throwonerror="yes" redirect="yes">
<CFHTTPPARAM name="UserName" type="FORMFIELD" value="blah1">
<CFHTTPPARAM name="Password" type="FORMFIELD" value="blah2">
</CFHTTP>
<cfcatch type="any">
<cfoutput>999<cfdump var="#cfcatch#"></cfoutput>
</cfcatch>
</cftry>
<cfdump var="#cfhttp#">
---------------------------------------------------------------

-------------------------Called page (reservation_intermediateTEMP.CFM) ---------------------------
 <cfloop list="#form.fieldnames#" index="i">
          <cfset string="form.#i#">
          <cfoutput> #i#: #evaluate(string)#</cfoutput><br>
        </cfloop>
            
---------------------------------------------------------------------------

CFDUMP in the caller page shows:

Filecontent USERNAME: blah1<br> PASSWORD: blah2<br>

which sounds correct to me except there is no redirect and there is no error either.

Any ideas?


 Hmm, could you tell me what it is you want as a result (what do you expect to happen)?

 The redirect parameter of the CFHTTP allows the CFHTTP to follow a redirect on the URL page.    But your URL page (reservation_intermediateTEMP.cfm does not perform a redirection (there is not CFLOCATION in it).  

 If you're expected your Calling Page to redirect after the CFHTTP command, simply add a CFLOCATION into the code.

Thanks again! All I want to do is to programmatically POST form data to another page in a way that I can see that another page after posting. Just like a regular human user would do.
Let me try the CFLOCATION thingy...
Thanks.
No, error, of course. The '...TEMP.CFM' page is now not getting the Form's data.

-----------------
The error occurred in C:\Inetpub\wwwroot\MonkeyJoesCFM\reservation_intermediateTEMP.cfm: line 1
 
1 :  <cfloop list="#form.fieldnames#" index="i">
2 :           <cfset string="form.#i#">
3 :           <cfoutput> #i#: #evaluate(string)#</cfoutput><br
 
-------------------------------
I just changed the code and tried something else but no luck. I think I am closer though. I am getting the same result as 'csteinola said on Sep 24, 2003 at 11:41 AM : ' in that thread. So how do I intepret it?

http://livedocs.macromedia.com/coldfusion/6.1/htmldocs/tags-p58.htm

--------------------Adobe's Reponse------------
With respect to the redirect attribute:
When ColdFusion executes a page with a CFHTTP tag with redirect="Yes", and it receives a redirection message in response to the HTTP request, it sends a request to the redirection target and handles the response as if it had been the result of the original request.
Also, the page should state ColdFusion does the redirection only if it receives both a Location header AND a 300-series (redirection) status code.
The example from csteinola tries to use a cfheader tag to force a redirection, but this does not send a 300 status, and therefore does not force the redirection.
(The cflocation tag does generate an HTTP 302 resonse with the url attribute as the Location header value.)
----------------------------------------------

 Ok, I understand what you're doing.

 So typically you would have a page called something like  ReservationForm.cfm, the user would fill out this form and submit it to the reservation_intermediateTEMP.CFM page which does the processing, right?

 So your CFHTTP post in "Calling Page" is *skipping the ReservationForm.cfm page and is posting directly to the action page.   Normally, I would think this would be the end of it, you have processed the form post, but you're saying the reservation_intermediateTEMP.CFM page, after processing, will do a redirect (let's ay to a page called "ThankYou.cfm" and you want to capture the contents of that page.

 As far as I can see the only thing your missing is the redirect in reservation_intermediateTEMP.CFM.

 If this is the code for it, where do you redirect?   Add a CFLOCATION to the bottom of it..

-------------------------Called page (reservation_intermediateTEMP.CFM) ---------------------------
 <cfloop list="#form.fieldnames#" index="i">
        <cfset string="form.#i#">
        <cfoutput> #i#: #evaluate(string)#</cfoutput><br>
  </cfloop>

  <CFLOCATION URL="ThankYou.cfm"  addToken="no">   <!---this is the redirection that will be captured -->


 Am I barking up the wrong tree?
 


 Regarding csteinola's post which I have pasted here...

>I would expect that the CFHTTP would follow the redirect="yes" attribute, and, since the response header contains a Location field, the form_ok.cfm page should be displayed.
But it doesn't. All I ever see is "Here I am on the posting page". If I check CFHTTP.FileContents, the ok page is there. And if I check cfhttp.responseHeader, the Location field contains the URL to the ok page.


csteinola seems not to understand what the redirect does.  He is expected the page viewed by the user to change, it will not.   The redirect="yes" parameter allows CFHTTP to follow a redirect that its called page may want to process.   The results are returned of that followed page, with redirect="No" the called page would not be allowed to redirect.  In either case the page viewed by the user never changes.  The only difference is what filecontent is returned by CFHTTP.

If your object is to change the page the user is viewing to whatever page the called page is redirected to, then capture the return value of cfhttp.responseHeader.location and then CFLOCATION to it.

 For example...

   <CFHTTP url="DOLOGIN.CFM" method="post" resolveurl="yes" throwonerror="yes" redirect="yes">
      <CFHTTPPARAM name="UserName" type="FORMFIELD" value="blah1">
      <CFHTTPPARAM name="Password" type="FORMFIELD" value="blah2">  
   </CFHTTP>

   <CFLOCATION URL="#cfhttp.responseHeader.location#"  addToken="no">  <!--- this will take you to HomePage.cfm ---->


 Where DoLogin.cfm is...

  ...  take the form.username and form.password command and validate them, etc etc.. etc..

 Then  do a

 <CFLOCATION URL="HomePage.cfm" addToken="No">


 
No, my friend. I do not want to go to some Thank you or home page etc. Here is what I am trying to do:

1) Page1.cfm: User fills out a form and clicks Submit which goes to Page2.cfm
2) Page2.CFM, CF Code checks for a certain variable's value (eg. Order Item1 is 'Yes' or 'No'). If 'Yes', go to Page3.cfm in such a way that Page1.cfm's FORM data get Posted to Page3.cfm. If 'NO', then, Page1.cfm's FORM data get posted to 'Page4.cfm' for further processing.

I thought CFHTTP will be able to help but so far not! There are so many FORM variables and I don't want to pass all that data using QueryString way.

Any idea?

Thanks a bunch!
ASKER CERTIFIED SOLUTION
Avatar of gdemaria
gdemaria
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Hey, the CFINCLUDE might be the better option! But, to answer your question:

Page1.CFM calls Page2.cfm. Page2.CFM -Should- do CFHTTP but it is not doing it! And that is simply the problem. So the logic of:
cfif OrderItem1 is "Yes">

     <cfhttp url="page3.cfm".... etc...>

 <cfelse>
   
      <cfhttp url="page4.cfm"  ... etc...>

 </cfif>

is not going to work because Page2.cfm, while POSTING form data to Page3.CFM does not actually go to Page3.cfm. It needs to Post to PAGE3.CFM and the content in the browser should be changed to that of Page3.cfm.

Any idea?

Thank you.
Irfan
PS. May be I am completely misunderstanding the concept of Redirect='yes' part?


Is there a type-o in this sentance?   You want it to post to page 3 and go to page5 perhaps?

> while POSTING form data to Page3.CFM does not actually go to Page3.cfm.
                                                                     ^^^^                     ^^^ Does not go to page 3 ?
> It needs to Post to PAGE3.CFM and the content in the browser should be changed to that of Page3.cfm.
                                  ^^^ page 3                                           ^^^^^                               ^^^ page 3




 Developers often set up "action" pages separate from pages intended for display.  So, a typical scenario may be..
 
 An action page just does updates, inserts, etc. (sometimes validation)  (I've added _ACT to show its an action)
 A display page is meant to be written to the screen   (I"ve added _DIS to show the display page)


  Page1_DIS.cfm

  show the form, posts to  page2_ACT.cfm

 Page2_ACT.cfm

 only processes, does not show anything

 <cfif OrderItem1 is "Yes">
      <cfinclude template="page3_ACT.cfm">
 <cfelse>
      <cfinclude template="page4_ACT.cfm">
 </cfif>


 In page2_ACT.cfm you can give a redirect to any page within the <CFIF (to make it dependant on the OrderItem flag) or outside the CFIF, like these:


 <cfif OrderItem1 is "Yes">
      <cfinclude template="page3_ACT.cfm">
      <CFLOCATION URL="page3_DIS.cfm">  <!--- only when YES ---->
 <cfelse>
      <cfinclude template="page4_ACT.cfm">
 </cfif>
 <CFLOCATION URL="page5_DIS.cfm">  <!--- all other times ---->



 Just as an option, here's a simple frame work that is commonly used.

 In this case, the page is posted to ITSELF (page1.cfm posts to page1.cfm)  and processes using cfincludes based on whatever action (or OrderItems value).

  If success, you have a redirect to the next page,  if failure, the form drops through to stay on Page1.cfm showing the same form values as the user entered.




<!--- this is the primary key for the data on this page, expect it to be passed,
      if it is empty, the page will create a new record ----->
<cfparam name="form.contact_id" default="">  
             
<cfset variables.error = "">  <!---- this variable will hold an error message, if a problem occurs ---->

<cfif IsDefined('form.submit')>  <!-- the page has been submitted, process action --->
  <cftransaction action="BEGIN"> <!--- a transaction ensure everything on page is saved together or rolledback on error ---->
  <cftry>  <!---- catch any errors in the cfcatch below ----->
   <cfloop index="ii" list="lastname,firstname,email">  <!--- validate required fields are not empty --->
     <cfif len(form[ii]) eq 0>
          <cfthrow message="Please supply all required fields">
       </cfif>
   </cfloop>
   <cfif Form.OrderItems is "Yes">
       <cfinclude template="page3_ACT.cfm"> <!--- this file inserts or updates the data --->
       <cfset variables.nextPage = "page5_dis.cfm">
   <cfelse>
       <cfinclude template="page4_ACT.cfm"> <!--- this file inserts or updates the data --->
       <cfset variables.nextPage = "page6_dis.cfm">
   </cfif>
   <cftransaction action="COMMIT">
  <cfcatch type="Any"> <!---- catch all errors, whether you cfthrow them or if happens in your sql statements ---->
     <cftransaction action="ROLLBACK">
     <cfset variables.error = cfcatch.message> <!---- set your error flag message variable ---->
  </cfcatch>
  </cftry>
  </cftransaction>
  <cfif len(variables.error) eq 0> <!--- if no error, go to your next page ---->
     <cflocation url="#variables.nextPage#" addtoken="no">
  </cfif>
</cfif>

<cfif len(variables.error) eq 0> <!--- this happens on first opening the file, get data ---->

   <cfquery name="getContact" datasource="#request.datasource#">
     select * from contacts
       where contact_id = #val(form.contact_id)#
   </cfquery>
   <!---- the next line will copy every column from the query into a FORM
          variable.  This will allow you to use the form scope below instead
              of the query name.  In case of an error, this allows your page
              to reload the entered values without saving them ---->
   <cfloop index="ii" list="#getContact.columnList#">
      <cfset form[ii] = getContact[ii][getcontacts.currentRow]>
   </cfloop>
   
</cfif>

<cfif len(variables.error) gt 0> <!--- if an error, show it ---->
  <cfoutput><span style="color:red">#variables.error#</span></cfoutput>
</cfif>
<!--- here is your form to get the data ---->

<cfoutput>
<form method="post">  <!---- No Action in form, page will post to itself ---->

 First Name: <input type="Text" name="firstName" value="#form.firstName#"><br><br>
 
 Last Name: <input type="Text" name="LastName" value="#form.lastName#"><br><br>

 Email: <input type="Text" name="email" value="#form.email#"><br><br>

 <input type="Submit" name="submit" value="Save">

</form>
</cfoutput>

No, it was not a typo! The basic problem remains: How to POST Form data from Page2.cfm to Page3.cfm or Page4.cfm using CFHTTP in such a way that the Form's data from Page1.cfm gets transfered to either Page3.cfm or Page4.cfm WHILE the browser shows content from either Page3.cfm or Page4.cfm.
I guess I need to move on! You have helped me enough for which much thanks. I am going to either implement the CFINCLUDE or simply pass the FORM's data as Query String.
Thanks again!

<
Is there a type-o in this sentance?   You want it to post to page 3 and go to page5 perhaps?

> while POSTING form data to Page3.CFM does not actually go to Page3.cfm.