Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hiya,
I am using DBI and CGI to interact with a MySQL database.
I have stored pathnames to images in the db.

I realise I need to use print "Content-type: image/gif\n\n"

But can I do this in a script that begins print "Content-type:text/html\n\n";?

Must I have two separate cgi scripts, or can I change content type halfway through ?
Also, how should I open the gif - Im thinking of this:
print "Content-type: image/gif\n\n"; open(MYFILE,"$picture_path") or die; binmode MYFILE; undef $/; my $pic = <MYFILE>; close MYFILE; print "Content-Type: image/gif\r\n\r\n"; binmode STDOUT; print STDOUT $pic;
If I need two separate scripts (one to display html text, the other a gif piccy)
can I call them from the same form ? Cheers,
basm101

Replies are listed 'Best First'.
Re: Content-type: html and images ?
by davorg (Chancellor) on Feb 10, 2003 at 13:36 UTC

    Each HTTP transaction (i.e. each call to your program) can only return one set of HTTP headers. Therefore it can only return one type of data. You would need to return an HTML page and where you want the image to appear, put an <img> tag where the source is to another (or maybe the same) CGI program which will return the image.

    Your code prints two "Content-type" headers. This can potentially present a problem to browsers as the second one will be interpreted as data. Also you should look at using CGI.pm to print your content-type headers as it will always do the right thing with end of line characters. Your two headers neatly illustrate that there is scope for confusion there.

    --
    <http://www.dave.org.uk>

    "The first rule of Perl club is you do not talk about Perl club."
    -- Chip Salzenberg

Re: Content-type: html and images ?
by pfaut (Priest) on Feb 10, 2003 at 13:45 UTC

    You can do this from one script provided that you determine whether you are providing HTML or an image before writing your headers to the browser and then write the appropriate header for the content you are sending. I have pages that present statistical information and also generate graphs using GD::Graph from a single script. The key is to generate your response before sending the headers so that you know what type of response you are sending.

    --- print map { my ($m)=1<<hex($_)&11?' ':''; $m.=substr('AHJPacehklnorstu',hex($_),1) } split //,'2fde0abe76c36c914586c';
•Re: Content-type: html and images ?
by merlyn (Sage) on Feb 10, 2003 at 15:47 UTC
Re: Content-type: html and images ?
by Jaap (Curate) on Feb 10, 2003 at 13:32 UTC
    You need 2 scripts.
    The first one generates HTML with a link to the image. The link might look something like <img src="script.pl?action=showImage&id=234">

    The script that makes the gif can print it straight from the database to STDOUT
      Thanks, but I'm still having problems :( a little more explanation would be great :)

      I'm confused about the showImage action.
      I have this in my html generating script:
      print STDOUT "<IMG SRC=\"show_pic.cgi\" action=showImage>";
      where show_pic is my gif printing script. I dont understand the showImage action.
      Say $gif_file is the pathname to the gif I want opening.
      Is the &id in Jaap's example giving the right image path to the gif displaying script ?
      (ie. 234 is the gif that would be opened)
      thanks

        Why do you always explicitly print to STDOUT? That's unnecessary unless you've used select to change the default output filehandle.

        You need to re-read the sugggest that you were given. "action" is a parameter to your CGI program. Therefore you should have this:

        print STDOUT "<IMG SRC=\"show_pic.cgi?action=showImage\">";
        or (more idiomatically)
        print qq(<IMG SRC="show_pic.cgi?action=showImage">);
        Then within show_pic.cgi you can check for the value of the "action" parameter and take appropriate action (i.e. returning either the HTML page or the image).

        --
        <http://www.dave.org.uk>

        "The first rule of Perl club is you do not talk about Perl club."
        -- Chip Salzenberg

Re: (nrd) Content-type: html and images ?
by newrisedesigns (Curate) on Feb 10, 2003 at 16:44 UTC

    Every page element that is not the HTML of the page requires a seperate request/response. For example, a simple HTML page with two images and a linked CSS requires 4 HTTP connections (one for the page, the CSS, and one for each image).

    You could roll the HTML and the image into one script.

    Sample page:

    <html> <head> <title>This is my page!</title> </head> <body> <p>A line of text</p> <img src="index.pl?image=img01"> </body> </html>

    The perl:

    use strict; use CGI; my $q = CGI->new(); my $image = $q->param("image") or ''; if($image ne ''){ print $q->header("image/gif"); ## print out the rest of image here } else{ print $q->header(); print $q->start_html("This is my page!"); ## print out HTML here... }

    Untested. While you're here... SIGN UP!

    John J Reiser
    newrisedesigns.com