Code to download an image without having to right click a link?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • w33nie
    New Member
    • Jan 2007
    • 56

    Code to download an image without having to right click a link?

    I was wondering what I would need to do to make a link, when clicked, download an image with the Save As dialog box, instead of just loading the image inside the browser.
    I know that MIME edit would be able to do this for my browser, but I want it scripted into my web site, because I can't tell all of my users to edit their browser's settings

    I don't want to have to right click the link & click save as,
    and I don't want to have to zip the file.

    & I was told a server side language should be able to do it.
  • Markus
    Recognized Expert Expert
    • Jun 2007
    • 6092

    #2
    scroll down to the part about content disposition

    Comment

    • w33nie
      New Member
      • Jan 2007
      • 56

      #3
      How do I get that in an html link though?

      Comment

      • Atli
        Recognized Expert Expert
        • Nov 2006
        • 5062

        #4
        Hi.

        Yes, this can be done using PHP.

        PHP can suggest to the browser that the "page" should be downloaded as a specified file type rather than displayed as HTML markup.
        Note that not all browsers are smart enough to accept this, but most of the major once are. (Last time I checked, of all the browsers I usually check my codes on, only Apple's Safari had some issues with this)
        (EDIT: Just checked it and it appears that they have fixed it :P)


        This is done, as Markus' link pointed out, via the header() function.
        It sets HTTP headers, which are sent as directions to the browser, specifying a number of things, amongst which are the file name and type.

        Try something like:
        [code=php]
        <?php
        $fileToSend = "myImage.jp g";

        // Set the headers, telling browsers that this is a JPEG image
        // and that it is called "myImage.jp g"
        header('Content-type: image/jpeg');
        header('Content-Disposition: attachment; filename="myIma ge.jpg"');

        // Send along the file size, just to be thorough.
        header("Content-Length: ". file_size($file ToSend));

        // Send the contents of the file
        readfile($fileT oSend);
        ?>
        [/code]
        Any decent browser will accept this as an image, and either display it as such or open a download dialog.

        Comment

        • Markus
          Recognized Expert Expert
          • Jun 2007
          • 6092

          #5
          Using what atli said, you'd pass an id through a link
          Code:
          http://example.com/imagedownload.php?id=image_name.jpg
          Then on the imagedownload.p hp you'd have atli's coding, but you'd substitute the "myImage.jp g" with the actual image name, and you'd also have to supply the MIME type.

          Comment

          • Atli
            Recognized Expert Expert
            • Nov 2006
            • 5062

            #6
            To add a bit to my earlier post...
            I did a little testing on this while back and found that setting the following headers will open up a download dialog in all of the major browsers. (IE, Firefox, Opera and Safari... at least)
            [code=php]
            header("Pragma: public");
            header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
            header("Cache-Control: private",false) ;
            header("Content-Disposition: attachment; filename=\"".ba sename($filenam e)."\";" );
            header("Content-Transfer-Encoding: binary");
            header("Content-Type: PHP Generated Data");
            header("Content-Length: ".filesize($fil ename));
            [/code]
            The Content-Type is set to an invalid type ("PHP Generated Data") on purpose, as all of the browsers I have tested this on automatically detect the file type when given an invalid Content-type.

            The various cache-control headers are set in an attempt to force the browser to always download the image, rather than displaying any cached version.

            Comment

            • Markus
              Recognized Expert Expert
              • Jun 2007
              • 6092

              #7
              Originally posted by Atli
              To add a bit to my earlier post...
              I did a little testing on this while back and found that setting the following headers will open up a download dialog in all of the major browsers. (IE, Firefox, Opera and Safari... at least)
              [code=php]
              header("Pragma: public");
              header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
              header("Cache-Control: private",false) ;
              header("Content-Disposition: attachment; filename=\"".ba sename($filenam e)."\";" );
              header("Content-Transfer-Encoding: binary");
              header("Content-Type: PHP Generated Data");
              header("Content-Length: ".filesize($fil ename));
              [/code]
              The Content-Type is set to an invalid type ("PHP Generated Data") on purpose, as all of the browsers I have tested this on automatically detect the file type when given an invalid Content-type.

              The various cache-control headers are set in an attempt to force the browser to always download the image, rather than displaying any cached version.
              Thanks for extra info there, atli!
              I'll remember that, as i hope the OP will.

              Cheers.

              Comment

              • w33nie
                New Member
                • Jan 2007
                • 56

                #8
                Great, thanks, I'll give this a whirl when I've got a bit of spare time.

                Comment

                • w33nie
                  New Member
                  • Jan 2007
                  • 56

                  #9
                  Hmm, okay, I'm sure the fact that didn't work has something to do with my poor attempt at it,

                  Here's the link that tries to start the download,
                  [html]
                  <a href="http://www.***.com/photos_download .php?id=<?php echo $photo_full; ?>" target="_blank" >
                  [/html]
                  and here's the PHP code on the download page,
                  [php]
                  $filename = $_GET['id'];
                  header("Pragma: public");
                  header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
                  header("Cache-Control: private",false) ;
                  header("Content-Disposition: attachment; filename=\"".ba sename($filenam e)."\";" );
                  header("Content-Transfer-Encoding: binary");
                  header("Content-Type: PHP Generated Data");
                  header("Content-Length: ".filesize($fil ename));
                  [/php]

                  This code results in this link on the page itself,
                  Code:
                  http://www.****.com/images/button%20-%20photo%20-%20download.jpg
                  Once clicked, opens a blank page to download the file. Although this page takes about 20 seconds to bring up the download dialog. It does eventually download the correct file (or atleast correctly named), but only a 1kb unworking version of it.

                  Comment

                  • w33nie
                    New Member
                    • Jan 2007
                    • 56

                    #10
                    can anyone help?
                    ...

                    Comment

                    • Markus
                      Recognized Expert Expert
                      • Jun 2007
                      • 6092

                      #11
                      Originally posted by w33nie
                      can anyone help?
                      ...
                      Hmm, content type: PHP Generated Data?

                      Try changing that to octet-stream

                      Comment

                      • Markus
                        Recognized Expert Expert
                        • Jun 2007
                        • 6092

                        #12
                        Originally posted by markusn00b
                        Hmm, content type: PHP Generated Data?

                        Try changing that to octet-stream
                        Or application/octet-stream

                        Not sure where the edit button has gone?

                        Comment

                        • w33nie
                          New Member
                          • Jan 2007
                          • 56

                          #13
                          No neither octet-stream or application/octet-stream worked,

                          & Just realised I made a mistake earlier with what the link ends up as,
                          it's actually this,
                          [html]www.***.com/photos_download .php?id=images/photos/France%20-%20Paris%20-%20Eiffel%20Tow er%20-%20Day%20-%2001%20-%20full.jpg[/html]

                          Comment

                          • Atli
                            Recognized Expert Expert
                            • Nov 2006
                            • 5062

                            #14
                            Try removing the path from the image name in your URL and add it in your code in stead. The extra / characters *may* cause some confusion.

                            Also, try it with an image that does not have spaces in the name. Spaces are represented by %20 in your URL. Don't know but that *may* be messing something up.

                            Changing the Content-Type should not have any effect. Any decent browser will automatically detect what it is downloading no matter what it says. (I've tested it! ^^)

                            Comment

                            • Atli
                              Recognized Expert Expert
                              • Nov 2006
                              • 5062

                              #15
                              Another thing I just noticed...

                              There isn't anything in the code you posted that prints the image data. Can we see that part to?

                              Comment

                              Working...