For Programmers: Free Programming Magazines  


Home > Archive > PERL CGI Beginners > August 2005 > Force a file download for link









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author Force a file download for link
Denzil Kruse

2005-08-30, 6:55 pm

Hi,

I want my users to download a csv file. When they
left click on the link, it brings the file up within
the browswer. They can of course do a right click and
"Save Target As" depending on the browser.

But I don't want to fuss with instructions and
users. I would just like the same thing to
happen as a "Save Target As" on a left click.

So I made something up, but it isn't working. I get
an internal server error from the browser. When I run
it at a command prompt, it seems to work fine.

Here is the code:

print "content-type: multipart/mixed\n";
print "content-disposition: attachment;
filename=SampleListingUpload.csv\n";

open (FILE,
"<$ABS_PATH/httpdocs/SampleListingUpload.csv") or
die "Unable to load the sample listing
template. Reason: $!";

my $text = join "", <FILE>;

close FILE;

print $text;

And here is the output from a prompt:

-bash-2.05b$ ./sample_listing.cgi
content-type: multipart/mixed
content-disposition: attachment;
filename=SampleListingUpload.csv
Keywords,Bid Amount,Title,Url,Description
home mortgage,0.10,ABC Home
Mortage,http://www.ABCHomeMortgage.com,Instant Quotes
tax attorney,0.75,ACME Tax
Attorneys,http://www.acmetaxattorneys.com,Let us
represent you
-bash-2.05b$

Does anyone know what I'm doing wrong?

Thanks,
Denzil

________________________________________
__________
Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com
Bob Showalter

2005-08-30, 6:55 pm

Denzil Kruse wrote:
> Hi,
>
> I want my users to download a csv file. When they
> left click on the link, it brings the file up within
> the browswer. They can of course do a right click and
> "Save Target As" depending on the browser.
>
> But I don't want to fuss with instructions and
> users. I would just like the same thing to
> happen as a "Save Target As" on a left click.


Very difficult to "force" the browser to do anything. The best you can do is
"suggest".

The most foolproof way is to use Content-Type: application/octet-stream (cf
RFC 2616, sec. 7.2.1). But that seems distasteful to me. Why lie about the
content type just because users are morons? Anyway...

Content-disposition is not part of the HTTP standard, so you'll get
inconsistent results.

Also, IE can think it's smarter than you are and inspect the URL for file
extensions instead of respecting your Content-Type header. Ain't life fun?

>
> So I made something up, but it isn't working. I get
> an internal server error from the browser. When I run
> it at a command prompt, it seems to work fine.
>
> Here is the code:
>
> print "content-type: multipart/mixed\n";
> print "content-disposition: attachment;
> filename=SampleListingUpload.csv\n";
>
> open (FILE,
> "<$ABS_PATH/httpdocs/SampleListingUpload.csv") or
> die "Unable to load the sample listing
> template. Reason: $!";
>
> my $text = join "", <FILE>;
>
> close FILE;
>
> print $text;
>
> And here is the output from a prompt:
>
> -bash-2.05b$ ./sample_listing.cgi
> content-type: multipart/mixed
> content-disposition: attachment;
> filename=SampleListingUpload.csv
> Keywords,Bid Amount,Title,Url,Description
> home mortgage,0.10,ABC Home
> Mortage,http://www.ABCHomeMortgage.com,Instant Quotes
> tax attorney,0.75,ACME Tax
> Attorneys,http://www.acmetaxattorneys.com,Let us
> represent you
> -bash-2.05b$


multipart/mixed is incorrect. text/csv is the proper MIME type for your
response. Also, your MIME header lines techincally need to end with \r\n,
and you must have emit blank line after the header.

This is why we always recommend using the CGI module. It gets this stuff
right.

use CGI qw(:standard);

open FILE, ...blah blah...
print header('application/octet-stream');
print while <FILE>;
Denzil Kruse

2005-08-30, 6:55 pm



--- Bob Showalter <Bob_Showalter@taylorwhite.com>
wrote:

<snip>
>
> use CGI qw(:standard);
>
> open FILE, ...blah blah...
> print header('application/octet-stream');
> print while <FILE>;
>


Thanks for the help Bob! Is there another way besides
the content-disposition to specify an attachment or
filename? I was trying to find a way to get a file
download box to come up to ask where to save the file
on their local computer. With just the above, it will
display it in the browser, and my users will just
go...huh?

Denzil

________________________________________
__________
Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com
Paul Archer

2005-08-30, 6:55 pm

You might want to look at how sourceforge.net handles things when you go to
download. I don't know the mechanism, but it's the behavior you want.

Paul

3:23pm, Denzil Kruse wrote:

>
>
> --- Bob Showalter <Bob_Showalter@taylorwhite.com>
> wrote:
>
> <snip>
>
> Thanks for the help Bob! Is there another way besides
> the content-disposition to specify an attachment or
> filename? I was trying to find a way to get a file
> download box to come up to ask where to save the file
> on their local computer. With just the above, it will
> display it in the browser, and my users will just
> go...huh?
>
> Denzil
>
> ________________________________________
__________
> Do You Yahoo!?
> Tired of spam? Yahoo! Mail has the best spam protection around
> http://mail.yahoo.com
>
> --
> To unsubscribe, e-mail: beginners-cgi-unsubscribe@perl.org
> For additional commands, e-mail: beginners-cgi-help@perl.org
> <http://learn.perl.org/> <http://learn.perl.org/first-response>
>
>


------------------------------------------------------
I recently heard that scientists have isolated the gene
that makes scientists want to isolate genes.
------------------------------------------------------
Wiggins d'Anconia

2005-08-30, 6:55 pm

Denzil Kruse wrote:
>
> --- Bob Showalter <Bob_Showalter@taylorwhite.com>
> wrote:
>
> <snip>
>
>
>
> Thanks for the help Bob! Is there another way besides
> the content-disposition to specify an attachment or
> filename? I was trying to find a way to get a file
> download box to come up to ask where to save the file
> on their local computer. With just the above, it will
> display it in the browser, and my users will just
> go...huh?
>
> Denzil


The 'header' function can take a key/value list of arguments to include
additional header lines. So you can pass your content-disposition header
as you had it before. The key here is that the content type be set to
'application/octet-stream' and that the disposition header will only
work if the client understands it, but in most cases it is worth a shot.

In one my libraries I use,

my %header_options = ( -Content_Type => 'application/octet-stream',
-Content_Length => $content_length,
);

if (defined $self->{'filename'} and $self->{'filename'} ne '') {
$header_options{-Content_Disposition} = "attachment;
filename=\"$self->{'filename'}\"";
}

It seems to have worked for me. Obviously you need to replace
$self->{'filename'} with your variable, and preferably set
$content_length with the file size.

HTH,

http://danconia.org
Denzil Kruse

2005-08-30, 6:55 pm



--- Wiggins d'Anconia <wiggins@danconia.org> wrote:
<snip>
>
> In one my libraries I use,
>
> my %header_options = ( -Content_Type =>
> 'application/octet-stream',
> -Content_Length =>
> $content_length,
> );
>
> if (defined $self->{'filename'} and
> $self->{'filename'} ne '') {
> $header_options{-Content_Disposition} =
> "attachment;
> filename=\"$self->{'filename'}\"";
> }
>
> It seems to have worked for me. Obviously you need
> to replace
> $self->{'filename'} with your variable, and
> preferably set
> $content_length with the file size.
>
> HTH,
>
> http://danconia.org
>


I just tried it by doing this:

print header(-type=>'application/octet-stream',
-attachment=>'SampleListingUpload.csv');

And it works for me. I didn't set the content length
because I don't know what the syntax is doing it this
way, and there wasn't an example in the for it in the
cpan cgi doc.

Someone said that the content-disposition wasn't
standard, so I thought this way would be better. Does
anyone see any issues doing it this way?

thanks,
Denzil



________________________________________
____________
Start your day with Yahoo! - make it your home page
http://www.yahoo.com/r/hs

Lewis Kirk

2005-08-30, 6:55 pm

At 1:41 PM -0700 8/30/05, Denzil Kruse wrote:
>Hi,
>
>I want my users to download a csv file. When they
>left click on the link, it brings the file up within
>the browswer. They can of course do a right click and
>"Save Target As" depending on the browser.
>
>But I don't want to fuss with instructions and
> users. I would just like the same thing to
>happen as a "Save Target As" on a left click.
>

I have used the ftp protocol to do that:

<a href="ftp://ftp.foobar.com/foobar.csv">FooBar CSV file</a>

Would that work?
--
Lewis Kirk
www.dmzgraphics.com
Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com