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

Hi Monks!
I've come to thee again for a cgi - cookie question.
I have a web page which accepts data
<html> <head> <meta http-equiv="Content-Type" content="text/html"> <title>Application</title> <Form method=post name="myForm" action="cgi-bin/details.pl"> ... ... ... <select size="1" name="application" style="font-family: Verdana; font- +size: 13px; border: 1px solid #000000; padding: 1; " size="6" maxleng +th="6" style="background:#D7DFEE;color:blue"> <option></option> <option value="CIDAccounts">CIDAccounts</option> <option value="Column_Financial">Column Financial</option> <option value="IFA">IFA</option> <option value="Imaging-Fax">Imaging-Fax</option> ... ... ... </Form> </body> </html>
The cgi perl script would take the input from the page, validate and enter the details to a text file.
#!c:\perl\bin\perl use strict; use CGI qw(:standard); my $okflag="y"; my @chk; my @InvalidFields = grep {not defined CGI::param($_) or CGI::param($_ +) eq ''} CGI::param(); ... ... ... my @ppl=param('coord'); my $reldate=param('date'); my $apps=param('application'); .. open FH, ">>report_sum.txt" or die "Cant open report_sum.txt Reason: $ +!"; print header; print start_html('Thank you'); print <<EOF; my $writestr=<a single string concatenated based on all the values> print FH $writestr."\n"; close FH; print end_html;
The issue Im facing is that if the user hits refresh in the page which is loaded by the cgi, and hits retry when prompted, the details are again written to the text file.
Since I have no clue about writing cookies, can anyone provide with a complete sample script that will implement the usage of cookies, based on the above scenario, so that there is no re-entry of the same data in the text file. If there's any other way to implement the way, I'll try that too.
Thanks for your time.

Did you ever notice that when you blow in a dog's face, it gets mad at you but when you take him on a car ride,he sticks his head out the window and likes it?

Replies are listed 'Best First'.
Re: CGI Cookie
by ajdelore (Pilgrim) on Sep 05, 2003 at 17:24 UTC

    I don't think you need a cookie. Instead of printing out a page from the CGI script, re-direct the user to a new page using an HTTP redirect.

    open FH, ">>report_sum.txt" or die "Cant open report_sum.txt Reason: $+!"; my $writestr="..." print FH $writestr, "\n"; close FH; print redirect("http://mysite.com/thankyou.html");

    NB: Make sure you don't print out anything else (including other HTTP headers) before the redirect.

    </ajdelore>

      Hi...
      Thanks for your "redirect" script. It was something new, though I remember using it some years back. I have a question: Suppose I'm entering the details and submitting a form, the thankyou.html would get created, and would contain either the message "entry successful" or "fields invalid" and would display in the browser (lets say it shows me "fields invalid"). Suppose someone else did the same thing at the same time, and he/she entered all the fields successfully, then the thankyou.html would show "entry successful". What will happen if I refresh that page? It would also show me "entry successful" right?

      I also thought of appending the thankyou.html with a timestamp, but that would lead to lot of such files getting created....
      Any alternatives?
      Thanks for your time.

      Did you ever notice that when you blow in a dog's face, it gets mad at you but when you take him on a car ride,he sticks his head out the window and likes it?
Re: CGI Cookie
by bradcathey (Prior) on Sep 05, 2003 at 18:04 UTC
    Maybe adjelore is right, you don't need a cookie, but just in case here's a little sample program that shows how easy it is to set and get cookies in Perl (easier that javascript, but then about anything is easier)
    #!/usr/bin/perl -w print "Content-type: text/html\n\n"; use CGI; $q = new CGI; ($sec,$min,$hr,$mday,$mon,$yr,$wkday,$yrday,$isdst) = localtime(); $end = $min + 20; if ($end > 59) { $end - 60; } print "Set-Cookie: endtime = $end\n"; #set the cookie print "Minutes to end: $min to $end\n"; #some significant pause $cookie = $q->cookie( "endtime" ); #get the cookie print "$cookie\n";
    And please, fellow monks, don't reply that I should have used strict, etc. I know, I know.

    And ajdelore thanks for the redirect sample, I've been using another way, I'll try this one.

    Brad
Re: CGI Cookie
by freddo411 (Chaplain) on Sep 05, 2003 at 22:20 UTC
    In answer to your general question, which I will rephrase as:

    I've got a form-->CGI scenario; let there be no re-entry of the same data.

    There are a number of things to consider.

    * What defines an invalid resubmission? Never twice by the same user? Never twice by the same machine/browser? (cookies come into play here) Never twice within 2 seconds /2 minutes / 2 hours? Perhaps one of the submitted fields can't be a duplicate?

    Any of the above ideas are the basis for a code-based solution for distinguishing valid submisssions.

    * If you do end up having the CGI set a cookie to indicate that this browser has submitted this form you'll run into a number of limitations. Cookies can be deleted due to space considerations. Your cookie won't be set prior to a user being able to click the submit button again (and again, and again).

    One idea to help prevent users from clicking a submit button multiple times is to have a javascript function hide the submit button and message the user (Processing...) after the first submission. Your CGI would continue to work as needed.

    A working example to put in your HTML:

    you can use this Javascript and this code snippet below, using the onsubmit attribute of the form tag.

    <script language="JavaScript"> <!-- function submitForm() { document.getElementById('submit').value = "Please Wait..."; document.getElementById('submit').disabled = "disabled"; return true; } //--> </script> <form method="post" action="login.asp" onsubmit="submitForm();"> <input type="text" id="price" name="price"><br> ... <input id="submit" name="submit" type="submit" value="Send data"> </form>

    Monks:
    Please don't flame me for not addressing this in perl. I'm not aware of any client-side perl and this particular problem needs to be addressed on the client-side.

    Cheers

    -------------------------------------
    Nothing is too wonderful to be true
    -- Michael Faraday