
|
View Full Version : How do you prompt "File Save as" ? without using "document.execCommand"
latheesan 07-31-2005, 11:53 AM Im created a file called d.php which takes the file name i am about to download and forwards it to a agreement page.
So, an example of downloading the file called dog.mp3 will be
http://www.mysite.com/d.php?file=dog.mp3
this request goes to a page called agree.php where on that page, it shows file's details like file name, size and last modified date and on the middle it has a little agreement box and at the very end it has the link to download the file.
this is the link part (the main problem i am having)
<td height="20" width="400" class="download">
<a href="[FILENAME]">[FILENAME]</a>
</td>
as you can see, the [FILENAME] is a macro that turns into a hyperlink like http://www.mysite.com/downloads/dog.mp3
the problem is, when ever i click on the link to download the file, it opens my windows media player and the video gets streamed, also people can leech off my site.
I tried using this method:
<a href="#" onclick="javascript:document.execCommand('SaveAs','1','[FILENAME]')">Click to save</a>
That method failed because it saves all the files in .htm or .html or .txt format for some reason
as you can see, im veryyy stuck :(
any possible ideas on how to over come this force downloading problem?
zoldar 07-31-2005, 01:33 PM It seems, that there's no one sure and good solution ( see http://www.htmlhelp.com/faq/html/all.html#force-download ).
The href would point to a php script:
<a href="file.php?file=[FILENAME]">Click to save</a>
And the file.php itself could conatin ie. :
<?php
header("Content-type: application/x-file-to-save");
header("Content-Disposition: attachment; filename=".$_REQUEST['file']);
readfile($_REQUEST['file']);
?>
latheesan 07-31-2005, 01:35 PM Wow, your code looks very promising, im going to try it immediately :)
zoldar 07-31-2005, 01:51 PM Pay your attention to the fact that this piece of code may be potentially insecure. Ie. somebody could invoke it like that:
http://www.mysite.com/file.php?file=/etc/passwd
One way of dealing with that is to configure php properly (safe_mode = On first - it prevents user from reading the file that he doesn't own).
Other one would be checking passed filename against some list of valid filenames (invoked by dir() command in proper dir, held in db or whatever.
These are not the only ways of securing it - maybe somebody has some better idea... ?
zoldar 07-31-2005, 02:05 PM Another one small correction to the code:
<?php
header("Content-type: application/x-file-to-save");
header("Content-Disposition: attachment; filename=".basename($_REQUEST['file']));
readfile($_REQUEST['file']);
?>
so that it wouldn't pass the whole path to the file as a filename.
latheesan 07-31-2005, 03:08 PM erm where would i have to place the above code in my d.php file?
<?
$filedirectory = 'http://localhost/site.com/mp3s';
$filepath = 'root\site.com\mp3s';
$template = 'agree.php';
if (!$file){
header("Location: http://localhost/site.com/index.php?id=InvalidRequest");
exit();
}else
if ( !file_exists("$filepath/$file") ){
header("Location: http://localhost/site.com/index.php?id=FileNotFound");
exit();
}else
$fp = fopen ("$template", "r") or die_nice("Could not open template file: $template");
$contents = fread ($fp, filesize ($template));
fclose ($fp);
$contents = str_replace("[FILENAME]", $file, $contents);
$contents = str_replace("[FILESIZE]", number_format(filesize("$filepath/$file")), $contents);
$contents = str_replace("[MODIFIEDDATE]", date("F j Y", filemtime("$filepath/$file")), $contents);
$contents = str_replace("[DOWNLOAD]", "${filedirectory}/$file", $contents);
print stripslashes($contents);
?>
zoldar 07-31-2005, 04:37 PM You've to change agree.php content. Can you put it here on the forum ?
Dan L 07-31-2005, 04:49 PM Try meta redirecting to the file.
latheesan 07-31-2005, 05:19 PM zoldar, i PM'ed you the simple version of the agree.php file
here it is again with the css and so on
latheesan 07-31-2005, 05:21 PM Thanks for you PM
I got your new solution, im going to try it immediately :D
Thanks once again
latheesan 07-31-2005, 05:26 PM Hey zoldar,
I didn what you asked me to do in the PM,
I placed your header script on the top agree.php and made the hyperlink like this
<a href="d.php?file=[FILENAME]">[FILENAME]</a>
and when i entered to try a download, i entered the url
http://www.site.com/d.php?file=song.mp3
it took me to the agree.php file, and then clicked on the hyperlink, then it just refreshed the page
so i was curious and right clicked on the link it created dynamically and see whats the url and it was this
http://www.site.com/d.php?file=song.mp3
Maybe this is why the page is keep refreshing, :bawling: how do i fix this now?
zoldar 07-31-2005, 05:35 PM Ok once again...
Keep file d.php UNCHANGED - i mean in the state it was before all the changes.
Change the agree.php as I have shown you in PM - EXACTLY like it was written
Then ADD file.php in the same directory where dl.php and agree.php scripts reside with following content:
<?php
header("Content-type: application/x-file-to-save");
header("Content-Disposition: attachment; filename=".basename($_REQUEST['file']));
readfile($_REQUEST['file']);
?>
latheesan 07-31-2005, 06:01 PM Hey thank zoldar,
Your suggestion worked great :D
ur da best man.
I'll be using this script to serve mp3 files only, at the moment the script is set to
Content-type: application/octetstream
what is the aplication type name thingy for MP3s?
zoldar 07-31-2005, 06:07 PM Mime-type (Content-type) is audio/mpeg
However don't set it to that, because then it will be treated with default action on the client side (opened in player in most cases) - and it was that, what you have wanted to avoid, haven't you. Setting these content related headers to something other does the trick.
gilbert 07-31-2005, 06:10 PM wow that looks like some neat stuff to do with php, good luck guys -gilbert
latheesan 07-31-2005, 06:15 PM Setting these content related headers to something other does the trick
Good idea indeed, so i set the header to the these format:
header("Content-type: audio/x-midi");
and i atempted to download a file through the d.php?file=nerd.mp3 and this is what happened (look at the attachement) :(
so i changed back to audio/mpeg and tried that as well, i keep getting that same file size and it wont download properly
the orginal file size is about 5mb, but through the script when i download, its about 223 byes EVERYTIME
why is it doing this?
zoldar 07-31-2005, 06:20 PM By 'something other' I mean something COMPLETELY other than any known media mime-type - like 'application/x-i-like-donuts' or 'application/x-whatever-else-you-want-to-put-here'
... and I hate donuts
latheesan 07-31-2005, 06:24 PM lolz, me too
latheesan 07-31-2005, 06:28 PM well, i changed the mime type to
"application/x-i-like-pie" lolz
but it stills downloads the files as 223 bytes wrongly
:( why???
zoldar 07-31-2005, 06:34 PM Try changing it to application/octet-stream and see if it behaves the same
latheesan 07-31-2005, 06:36 PM I changed it to "application/octet-stream" and it still downloading the file wrongly at 223 bytes :(
latheesan 07-31-2005, 07:57 PM Hey guys, Zoldar helped me fix it. Thank man, great work :D
|