-1

okay so it is appearing to me my header() isn't doing anything. i tried moving it to the very top of the file instead nothing changed unless I put it in its own but then the rest of the file doesn't run but it does send the header.

EDIT: I updated my code with your suggestions, but it still isn't working correctly. Below is an image of the network tab when I inspect the page. The big thing I notice is the calls are being made but its fetching the same about of data for every image and its a very tiny amount of data. enter image description here

edit: I am getting and Invalid URL Error when I inspect in chrome unless I remove data:image/png;base64,

Referrer Policy: strict-origin-when-cross-origin

I can't seem to get this working correctly. The png image should be pulling from the database and then displaying in the HTML. (and yes I know this isn't SQL injection safe) I assume there is some issue with it being called from the loop, but I am unsure. Or that it can't find the getImage.php to use it this way do i need to import it or something earlier in the code? It does correctly pull in the item_id. The result just gives me a broken image box. I know my getImage.php is outputting the correctly formatted image, because I have taken the output directly from there and inserted in place of the call for it and the image has show up. So it tells me this line below is my issue

echo ('<td><img src='"getImage.php?image_id="'  . $row["item_id"].'"></td><td>');

if I edit as follows it works fine (but obviously it give me the same image for every entry) DBS is the decoded byte string that getImage.php outputs

echo ('<td><img src="data:image/png;base64,DBS"></td><td>');

PHP for the Front Facing page (blackmarket.php:

    $sql="SELECT * FROM `item` WHERE 1";
  $result = $link->query($sql);
  echo("<table>");
    if ($result->num_rows > 0) {
    // output data of each row
    echo("<tr>");
    while($row = $result->fetch_assoc()) {
      $newrow=0;
      echo("<td>");
      echo ('<img src="getImage.php?image_id='.$row['item_id'].'" />');

getImage.php:

  <?php
    require_once "connect.php";
    if(isset($_GET['item_id'])) {
        $sql = "SELECT item_img FROM item WHERE item_id=" . $_GET['item_id'];
        $result = mysqli_query($link, $sql) or die("<b>Error:</b> I can't find the image <br/>" . mysqli_error($link));
        $row = mysqli_fetch_array($result);
        header("Content-type: image/png");
        
        header("Content-Length: " . strlen($row["item_img"]));
        echo  $row["item_img"];
    }
    mysqli_close($link);
JustOneGeek
  • 374
  • 2
  • 3
  • 12

3 Answers3

0

Just specify

echo "<td><img src=\"getImage.php?image_id={$row['item_id']}\"></td>";

The browser is responsible for assembling the page, and makes a separate call to the getImage.php script and reads the image data that you are returning.

Return the binary image data directly, along with the size. This might also be part of the problem.

<?php
    require_once "connect.php";
    if(isset($_GET['item_id'])) {
        $sql = "SELECT item_img FROM item WHERE item_id=" . $_GET['item_id'];
        $result = mysqli_query($link, $sql) or die("<b>Error:</b> I can't find the image <br/>" . mysqli_error($link));
        $row = mysqli_fetch_array($result);
        header("Content-type: image/png");
        header("Content-Length: " . strlen($row['item_img']));
        echo $row['item_img'];
    }
    mysqli_close($link);

Omit the closing php end tag ?> from this script. PHP best practices is to omit it for all scripts but it is especially important in a script like this that returns binary data, as a bit of whitespace or a UTF-8 BOM character can corrupt your output and is often hard to debug.

gview
  • 14,876
  • 3
  • 46
  • 51
  • looks like your just saying the add those braces... I tried that but it didn't work – JustOneGeek Oct 15 '20 at 03:13
  • noticed inspecting in browser that it am getting invalid URL for everything in the – JustOneGeek Oct 15 '20 at 03:20
  • @JustOneGeek I think you should return URI schema from PHP page as well. – Sameer Kumar Jain Oct 15 '20 at 03:40
  • @SaachiTech I am not sure what you mean – JustOneGeek Oct 15 '20 at 03:56
  • 1
    My primary point was that you do not need, nor should you be using in this case, the `data:image/png;base64` part because you do not have an inline image. You are specifying the `src=url`. That should be enough. Try just returning the image data rather than base64 encoding it. – gview Oct 15 '20 at 14:18
  • The manual `Content-Length` header shouldn't be necessary; the web server will calculate that automatically just like it would for an HTML page. – IMSoP Oct 15 '20 at 18:43
0

You are confusing two things:

  • data: URIs allow you to embed an image directly in the source code of an HTML page, so that the browser can render them immediately without another call to the server. They use base64 to make the data consist only of text, because you can't put non-text characters in the middle of your HTML source code
  • Normal https: URLs tell the browser to make a request to the server, which returns the image data, with no extra encoding needed. Most commonly, the web server will load the image straight from disk, but the browser doesn't know about that, so you can just as validly have a PHP script which returns the same data, based on whatever logic you want.

In your code, you've mixed the two: you've prefixed a normal URL with data:, so the browser is expecting the data right there in the source code, and never makes a call to getImage.php.

What you need to do instead is make sure that in your getImage.php you

  • echo out just the image data - no whitespace or debug output mixed in
  • not base64 encoded (if it's stored in the database that way, decode it before sending to the browser)
  • tell the browser it's an image with an appropriate Content-Type header, e.g. header('Content-Type: image/png'); - again, no mention of base64 encoding or anything else, you're serving an image just as if it was a file on your server

You shouldn't need to set the Content-Length header manually, the server will sort that out just like it would if you were outputting HTML

You can then load that image URL directly in the browser and it should display, no need to even look at your HTML until that part is working right.

IMSoP
  • 89,526
  • 13
  • 117
  • 169
  • well you got that right but changing this doesn't solve my issue..I am updating my code to so my current code – JustOneGeek Oct 15 '20 at 16:58
  • @JustOneGeek See updated answer. The key is always to break the problem down, which in this case means ignoring the HTML until you have the image loading correctly. – IMSoP Oct 15 '20 at 18:30
  • I should have mentioned when I used the getimage.php with the .decode in it and ran it it gave me the correct byre code.. I used that output and placed it in an img call (along with the image/png, base64) and it outputted correctly – JustOneGeek Oct 15 '20 at 19:21
  • so when I navigate to url/getImage?item_id=8000 if get �PNG IHDR�v�'�7"�zTXtRaw profile type exifxڭ� which isnt that what i should be seeing? – JustOneGeek Oct 15 '20 at 19:59
  • @JustOneGeek That looks like the contents of the image file, but your browser hasn't seen that it's an image. That suggests you haven't sent the Content-Type header correctly, it needs to be exactly "Content-Type: image/png", nothing else. – IMSoP Oct 15 '20 at 20:25
  • Yeah I have changed it to that and that is what it shows – JustOneGeek Oct 16 '20 at 05:24
  • @JustOneGeek If you go to the image URL, you should see it the same as if you go to any other image URL, like https://i.stack.imgur.com/skQUT.png You shouldn't see the file contents displayed in the browser as text. Check the network tab of your browser's F12 tools to make sure the `Content-Type` header looks right. – IMSoP Oct 16 '20 at 08:13
  • I am not sure where I would find the content-Type header in the f12 tools – JustOneGeek Oct 16 '20 at 18:16
0

Well I finally figured out what was going wrong. In my connect.php I had some white space and that white space was being called before my header so my header wouldn't work

JustOneGeek
  • 374
  • 2
  • 3
  • 12