Jump to content

Forcing save as dialog for image files not working


Chappers

Recommended Posts

Hi everyone,

I'm trying to force the browser to bring up a 'save as...' dialog box when a download link is clicked which is linked to a jpg image file, instead of opening the image in the browser.

After searching the net, I found the same snippet of code all over the place for doing this, but it won't work properly for me. Here's how the href link looks for a given image file:

[code]<a href="image.php"><img src="images/save.gif" alt="save"></a>[/code]

So when the link is clicked, it references the image.php file, inside which is the following:

[code]<?php
header('Content-disposition: attachment; filename=mypicture.jpg');
header('Content-type: image/jpeg');
readfile('images/mypicture.jpg');
?>[/code]

Now, I know that there can be no blank lines after the php code, or garbage may be added to the image file as it's rebuilt. The problem is that although this works and brings up a save as box, when you save the file, it's a 0Kb file.

It's the same behaviour as happens if you tell it to use a file that doesn't exist in the 'readfile' area. But I know the file is there and the address for the image file is correct and is how it's used on the rest of the site. I have the root directory on the server, with the "images" folder in the root, so image links are usually simply a href=images/whatever.jpg.

Can anyone help shed light on what's going wrong please?
Link to comment
Share on other sites

Thanks for the link. The code it gives is:
[code]<?php
$file = $_REQUEST['file'];
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Content-Type: application/force-download");
header( "Content-Disposition: attachment; filename=".basename($file));
header( "Content-Description: File Transfer");
@readfile($file);
?>[/code]
Where the download link would be something like: a href=image.php?file=/images/example.jpg

It gives the same results as original code I posted though: downloaded file is 0Kb, as though it's not finding the jpeg image in the first place and so is making an image with the name I tell it to use, but which consists of no data. For the code above, I changed content-type to image/jpeg.

Any idea what I'm doing wrong?
Link to comment
Share on other sites

i would suggest trying to read the file without forcing a download to see if it's even finding the file.  otherwise instead of using readfile(), you could try using filesystem functions to see exactly where it's going wrong:

[code]<?php

$handle = fopen($filename, 'r') or die('couldnt open file');
$contents = fread($handle, filesize($filename)) or die('couldnt read file');
fclose($handle);

echo $contents;

?>[/code]

these few lines would replace readfile().
Link to comment
Share on other sites

Thanks again for the help, I appreciate it.

Tried removing headers so file read like:
[code]<?php
$file = $_REQUEST['file'];
@readfile($file);
?>[/code]
But just get a blank page.

Not sure if that's exactly what you meant... sorry, still struggle with PHP.

Then did next suggestion of replacing @readfile with the code supplied, so it looked like:
[code]<?php
$file = $_REQUEST['file'];
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Content-Type: application/force-download");
header( "Content-Disposition: attachment; filename=".basename($file));
header( "Content-Description: File Transfer");
$handle = fopen($file, 'r') or die('couldnt open file');
$contents = fread($handle, filesize($file)) or die('couldnt read file');
fclose($handle);
echo $contents;
?>[/code]

And it worked perfectly, the file downloaded and I opened the image to check it and it was fine.

So just curious, can I leave the code as above since it works? And, out of curiosity, why doesn't @readfile work, yet the code you gave me with which to replace readfile works perfectly?

Thanks for time and help.
Link to comment
Share on other sites

Right, I did it this way, although not sure if it's the right way:
[code]<?php
$file = $_REQUEST['file'];
$contents = readfile($file) or die('couldnt read file');
echo $contents;
?>[/code]
And it opened a new page stating 'couldnt read file'.

If I simply left the code alone and removed the headers and @:
[code]<?php
$file = $_REQUEST['file'];
readfile($file);
?>[/code]
I just got a blank screen.

If this isn't what you meant, could you supply the code to try, please?
Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.