4 Replies Latest reply on Mar 31, 2010 8:05 PM by meet_nagi

    Seam and browser back button

    meet_nagi

      Hi,


      We are using Seam 2 in our project and we follow stateless navigation where user can access any page and browser's back button should be enabled.


      The requirement is that when user clicks the browser back button I need to issue a fresh GET of that page to avoid any duplicate post data submits. In order to do that I need to track the user's browsing history.


      Please let me know your suggestions / best practises for the below:


      1) How to issue a GET on click of browser's back button
      2) How to maintain the browsing history.


      Thanks in advance.


      Nagesh

        • 1. Re: Seam and browser back button
          sburrows

          The problem you have is that when someone clicks the backbutton, the user's browser renders the page from it's internal cache.  You can't control what happens when the user clicks the back button. 


          The only thing you can do is disable caching on each page (via pragma no-cache, and other headers), but that can be unreliable because it's only a suggestion to the browser and behavior can vary from one browser to the next.  Further, if there are other caching mechanisms between the browser and the server, you still may not get what you want, and even if you did, you've eliminated one of the main browser performance features.


          If anyone does know how to do this I'd love to know, but I don't there is a way.


          Steve.

          • 2. Re: Seam and browser back button
            idyoshin

            hello community,


            I've faced the similar problem, and found following solution:



            public class CacheControllPhaseListener implements PhaseListener
            {
                 public PhaseId getPhaseId()
                 {
                      return PhaseId.RENDER_RESPONSE;
                 }
            
                 public void afterPhase(PhaseEvent event)
                 {
                 }
            
                 public void beforePhase(PhaseEvent event)
                 {
                      FacesContext facesContext = event.getFacesContext();
                      HttpServletResponse response = (HttpServletResponse) facesContext
                                .getExternalContext().getResponse();
                      response.addHeader("Pragma", "no-cache");
                      response.addHeader("Cache-Control", "no-cache");
                      response.addHeader("Cache-Control", "no-store");
                      response.addHeader("Cache-Control", "must-revalidate");
                      response.addHeader("Expires", "Mon, 8 Aug 2006 10:00:00 GMT");
                 }
            }



            and in faces-config.xml


                 <lifecycle>
                     <phase-listener id="nocache">com.uniqa.session.CacheControllPhaseListener</phase-listener>
                 </lifecycle>





            hope this gives a good starting point.


            Nevertheless - this works pretty fine for me.



            Kind regards,
            Ilya Dyoshin

            • 3. Re: Seam and browser back button
              sangaurav

              Nagesh,


              You can use the solution posted by Ilya. Even I'm using this in my application.


              But in certain scenarios even this won't help. Like if you perform submit operation on a page and then postback to the same page without any redirect i.e showing page in response to POST request.


              After post-back, move to any other page in your application and then press back button or just press refresh button on the page where from where you performed submit operation (initiated POST request).


              Whenever POST request is resubmitted, browsers either show warning messages (like in IE and Chrome) or confirmation dialog boxes(like in Mozilla). In case the user press reload/refresh despite of these warning then duplicate submit is performed.


              It is possible to get rid of these irritating messages and duplicate submits by using PRG (Post-Redirect-GET) design pattern.


              After POST request, redirect to the same view-id from which the request is initiated. This way the response would be generated via Get request. Browsers don't ask for confirmation when GET request is resubmitted.


              Here the catch is the data submitted in the POST request wouldn't be available after redirect if there is no page-load action is associated with that view-id.


              To resolve this you can use Conversation scope as it keeps data even after redirect.


              I have implemented the similar solution in my appliation and it's working perfectly as required on IE/Mozilla and Chrome.


              The behavior is little different on Chrome because it caches 301 redirects. But it doesn't cause any problems so far.


              I hope this will help you in your application.


              Regards,
              Gaurav Saini


              P.S.: Please rate if this helps anyone.

              • 4. Re: Seam and browser back button
                meet_nagi

                Thanks to both Ilya and Gaurav for your response.


                I have used the Ilya's implementation of PhaseListener and it is working fine.
                Gaurav,I yet to test the scenarios mentioned by you and will follow your suggestions incase of any issues.


                Thanks again to both of you for your valuable suggestions.