Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hi, I was going through the CGI documentation and I couldn't find how to do this. What is the CGI equivalent of the javascript history.back() or history.go(#) functions? (in case the name of the function is not self-explanatory enough, what I am trying to accomplish is move the user through his/her browser history) Thanks,

Replies are listed 'Best First'.
Re: history.back()
by fmerges (Chaplain) on Jun 24, 2005 at 14:04 UTC
    Hi,

    By server-side you must do it another way... Two approaches could be:

    One step back -> using $ENV{HTTP_REFERER}

    Another possibility is using cookies or sessions to store the movement through your website.
    And then showing a list of pages visited before, reading the stored cookie or session info.

    Other thing that could be useful is HTML::Breadcrumbs

    Regards,

    :)

      HTTP_REFERER can't really be trusted, as it's input, and so should be considered tainted. Some browsers don't populate it at all (for security reasons), or selectively populate it (browsers aren't supposed to populate it if they follow a link from HTTPS to HTTP)

      I also wouldn't suggest going with a session approach, as the user may spawn multiple windows, and so the last page they visited in that session may not be the last session in that window.

      I think a breadcrumb approach is good, and just tell the user to click on it.

      or you can do another potentially bad thing, and confuse the hell out of your visitors:

      print <<EOF; Content-type: text/html <html><head><title>Go Away!</title></head> <body onload='history.go(-1);'></body></html> EOF

      Typically, if I have a page that is going to need to send someone back to where they came from, I'll do like tlm suggested, and send the location they came from in a hidden field (eg, if they trigger a page that needs authentication, I'll pass them to the authentication page, but keep track of where they tried visiting, so that after they authenticate, I can send them back to where they were trying to go)

Re: history.back()
by hardburn (Abbot) on Jun 24, 2005 at 13:46 UTC

    Perl generally works on the server side. JavaScript generally works on the browser side. The server does not have access to the browser's history, so it is inaccessible to Perl.

    "There is no shame in being self-taught, only in not trying to learn in the first place." -- Atrus, Myst: The Book of D'ni.

      #!/path/to/perl use strict; my $q = CGI->new(); print $q->header(); print qq(<script>history.go(-1);</script>); exit;
      If I recall correctly, history.back() is not cross-browser friendly.
Re: history.back()
by tlm (Prior) on Jun 24, 2005 at 14:13 UTC

    I'm no CGI expert, but my intuition tells me that this is a bad idea. (Call it a case of "CGI code smell".)

    But, FWIW, if the backtracking is to some form whose contents you control, I suppose that this form could pass (in a hidden field(s)) its identity and whatever extra information may be necessary to recreate it. Heck, I suppose it could pass its entire HTML (with allowances for the impossibility of infinite regress) as a quoted string in some mongo hidden text field...

    I'm sure there are many problems with this approach. (E.g. what if the user wants to hit "back" twice? How much backtracking info will you burden each page with?)

    the lowliest monk

Re: history.back()
by TedPride (Priest) on Jun 24, 2005 at 20:02 UTC
    HTTP_REFERER should work fine. If it's set to an incorrect value, that just means the person viewing your page is trying to spoof, and who cares if their links get messed up? Heck, I'd consider that a bonus. Of course, if you go forward enough and then back, the pages before may not be cached, and when they get regenerated, the HTTP_REFERER may no longer be there. One possible solution to this might be to use HTTP_REFERER if it's set, but otherwise make the link be Javascript, which should take care of almost all remaining situations. Session recordings can be used as well, but these have serious problems of their own if people open multiple windows or decide to refresh a page earlier in the chain. I'd personally go with the combination of HTTP_REFERER and Javascript.
Re: history.back()
by aditya.singh (Acolyte) on Jun 27, 2005 at 09:24 UTC
    There is no way to do that assuming you want your app. to run seamlessly across all web-browsers. The back button on mozilla is the best option.