Forum Moderators: coopster & phranque

Message Too Old, No Replies

print "Location:..." doesn't work when called via SSI

Any solution to have one CGI script call another CGI script would help...

         

MichaelBluejay

10:04 pm on May 19, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Before I describe my specific problem let me describe my overall goal, because there might be a better way to do it then what I'm trying to do.

My mom's site gets lots of visitors but few buyers. So my idea is that I put a small black bar at the very top of the page that tells users that if they order in the next 30 minutes they get 10% off. I figure that I'd implement it like this:

1. Put <!--#include virtual="countdown.cgi"--> at the top of each .html page.

2. <countdown.cgi> tries to read a cookie.

---- 2a. If the cookie exists I read the time it was set, figure out how much time remains, and output the number of minutes remaining to my black bar.

---- 2b. If the cookie doesn't exist then <countdown.cgi> calls <setcookie.cgi>, which sets the cookie and then returns the user to the original <.html> page.

Where I'm stuck is (2b): My [print:"Location..."] doesn't work when it's in a CGI file that's called via SSI, it works only if the CGI file is called directly.

I can think of two possible solutions, neither of them attractive:

A: Have JavaScript try to read and set the cookie. Downside is that it won't work if JavaScript is off, and I like to avoid JavaScript when I can.

B: Make each file on the website a <.cgi> file instead of a <.html> file, and have it run the code and then build the page. But this adds another level of complexity that I'd really, really prefer to avoid.

Any ideas? Thanks for your help!

volatilegx

3:11 pm on May 20, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Maybe if you put the SSI before any other text on the page the Location header would be sent before any other headers.

I'm not sure if it will work with SSI, but that's what I'd do in PHP to get it to work.

VectorJ

6:32 pm on May 20, 2004 (gmt 0)

10+ Year Member



It's not a solution but to help figure out what's going on, I'd print out a "Content-type: text/html\n\n" header in the setcookie.cgi script as the first line, then you'll be able to see the output from the script when it's called by SSI. You may be able to see some output being sent to the browser before the Location header is sent, and figure out how to correct the problem.

Also, check your error logs. Your script could be throwing an error when called by SSI that it doesn't throw when called directly.

upside

6:34 pm on May 20, 2004 (gmt 0)

10+ Year Member



You can't set or get a cookie from a script called via SSI. The reason is that the webserver is executing the script, not the user, and therefor the script does not have access to the user's cookies. You could call the countdown.cgi by using an iframe or JavaScript without having to rework your pages too much.

VectorJ

7:22 pm on May 20, 2004 (gmt 0)

10+ Year Member



Ah, okay, I just realized what's happening here. Since your first CGI is being called via SSI, the headers for the page have already been sent and a cookie can no longer be set. You should refresh to setcookie.cgi (rather than including it with SSI) by sending a "Location: setcookie.cgi\n\n" header from countdown.cgi, then have setcookie.cgi refresh back to the originating page via "Location: $ENV{'HTTP_REFERER'}\n\n".

volatilegx

4:20 am on May 21, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I apologize in advance for giving a PHP example in the Perl forum, but I know it will work.

I run a site that does something similar and my solution was to code the pages in PHP (very little coding difference from HTML pages actually... PHP is merely embedded in the file). In the first line of each file I begin the PHP code, read and set cookies, etc. This is possible because you can set cookie (and other) headers using PHP if you do it before any other headers (ie the Content-type: header) are set. To do this, you embed the Cookie setting PHP code before anything at all is output to the browser. Here's an example:

<?php
if ($CookieName){
$cookieData = explode("&", $CookieName);
$this = current($cookieData);
while ($this){
$temp = explode("=", $this);
$cookieHash['$temp[0]'] = $temp[1];
$this = next($cookieData);
}
$AccessTime = $cookieHash['time'];
} else {
$AccessTime = mktime();
}
setcookie("CookieName", "time=".$AccessTime, time() + (365 * 86400), '/', 'yourdomain.com');
# in the next line, 108000 is the number of seconds in 30 minutes...
$CountDownSeconds = $AccessTime - mktime() + 108000;
$CountDownMinutes = round(($CountDownSeconds/60),0);
?>
<html>
<head>
</head>
<body>

<?php
if ($CountDownMinutes > 0){
?>
<center>
<h2>Welcome to Our Countdown Sale!</h2>
<p>Purchase within <b><?php echo $CountDownMinutes;?> minutes</b> and we'll give you 6% off our already ridiculously low prices!</p>
<?php
}
?>

</body>
</html>

Something like that...

MichaelBluejay

9:21 am on May 22, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Thanks very much, this is great stuff. I'll try these things out, and I'll try to remember to post back here to report on how it went....

Thanks again, -MBJ-