Mark Wheeler wrote:
> Hi,
> 
> I'm having a problem with redirecting (Location: script.cgi) after a 
> file has been downloaded.
> 
> Here is the gist of the script. It creates two files (one html, the 
> other text), then a download dialog box comes up so the first newly 
> created file can be saved. But after the file is saved, I'm trying to 
> call the script again to download the second file, as I can't seem to 
> get the second file to download after the first one has finished. But 
> all I am getting is the first file downloaded with the 'print 
> "Location: script.cgi?text\n\n"' at the bottom of the saved file. Do I 
> need to change the Content-type or something to be able to call the 
> script again? Here is a sample of the script.
> 

I don't think what you are doing is possible. The reason is that the
browser is only expecting one set of headers. The "Location" is just a
special header, meaning I am sending you somewhere else as opposed to
giving you content. The problem is that by the time you send the
location, you have already provided a valid and full set of headers and
everything following is *just* content including the location string. So
it looks to the browser sort of like....

-- Begin Header --
...
Content-Type: text/html\n\n
-- End Header --
-- Begin Content --
blah blah blah...
Location: script.cgi  ## I don't recognize new headers!
-- End Content --

Which is why the location shows up in your saved file. MIME e-mail
allows additional sets of headers for attachments by including
boundaries, etc. but to my knowledge there is no way to do that over HTTP.

Theoretically you could accomplish the same goal by using a bit of
client side stuffs, for instance print an HTML page that has a
javascript onLoad that pops up a window or two that handles the download
call, or you could use a "hidden" frameset that calls each of the
downloads in a frame that has no height or width, though in this case
the browser location bar won't be changing (or appear to be) and you
will then have to worry about escaping back out of the frameset. I
suspect there might be a way to get this to work using objects, or
something similar like that but that is beyond my knowledge. There is
also the new XMLRequest (aka Ajax) stuff but I haven't had time to read
up on it so  don't know if it is appropriate for this problem, nor how
many browsers support it, though Google seems to think enough do to use it.

> Any ideas would be very helpful. Thanks very much,
> 
> Mark
> ------------------------------------------------------------------------ -
> 

HTH,

http://danconia.org

> <CODE>
> 
> my $request = $ENV{'QUERY_STRING'};
> if ($request eq "text") { &save_text; exit; }
> 
> # Create the files
> .
> .
> .
> #===========================
> # Save HTML version
> #===========================
> 
> &save_file($htmlname);
> 

Drop the ampersands, that is old style and they shouldn't be needed here.

> print "Location: script.cgi?text\n\n";
> 
> exit;
> 
> #===========================
> # Save TEXT version
> #===========================
> 
> sub save_text {
> 
> &save_file($textname);
> 

Where did $textname come from, are you using 'strict' and 'warnings'?
Your encapsulation is really severly broken.

> print "Content-type: text/html\n\n";
> 
> print "finished.";
> 
> exit;
> 
> }
> 
> #===========================
> # Save files
> #===========================
> 
> sub save_file {
> 
> my $path = "$pathtofile$_[0]";
> my $filename = $_[0];
> my $size = (stat($path))[7]; # the size, in bytes
> binmode STDOUT;
> 
> print "Content-Length: $size\n";
> print "Content-Disposition: attachment;filename=$filename\n";
> print "Content-Type: application/octet-stream\n\n";
> 
> open (FILE, "< $path") || die("Can't open($filename): $!");
> binmode(FILE);
> 
> my $data;
> while(read(FILE,$data,4096)) {
>     print $data;
> }
> close(FILE);
> 
> }
> 
> </CODE>
> 
> 

Reply via email to