Why is Varbinary Image Data being interpreted as text and not an image?

Advertisements

What I’m trying to accomplish is serving varbinary data through php back to the browser. I’ve tried just about everything. I’ve set the header('Content-Type: image/jpeg');
I’m testing this program right now by uploading a jpeg image through the HTML having the javascript grab it then send an XMLHttpRequest(); to a php file that as you can see takes the base64encoded data and turns it back in to binary image data then ‘expectedly’ is supposed to return it to the browser in a specified image tag. Well that doesn’t work. Here is the reproducible example.

<?PHP
  ini_set('memory_limit', '1024M');
  /* 
    Must have more than 512MB memory_limit
  */
  ini_set('error_reporting', E_ALL);
  ini_set('display_errors', 'On');
  function uploadImage($conn) 
  {
    $encodedData = $_POST['URLData'];
    $data = json_decode($encodedData);
    
    $name = $data->name;
    $qr = $data->qrDataUrl;
    $file = $data->fileDataUrl;

    $baseDataURL = explode(',', $file)[1];
    $decodedData = base64_decode($baseDataURL);

    echo $decodedData;
  }
  if (isset($_POST['URLData'])) 
  {
    try 
    {
      $connection = array("Database" => "", "UID" =>"",
                          "PWD" =>"");
      $conn = sqlsrv_connect('', $connection);

      uploadImage($conn);
    }
    catch(Exception $e)
    {
      echo $e->getMessage();
      die();
    }
  }
?>
<!DOCTYPE html>
<html>
  <head>
    <meta charset='UTF-8'>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="Stylesheet2.css">
    <link rel="stylesheet" href="Stylesheet.css">
    <script src="javascript/qr.js"></script>
  </head>
  <body>
    <div class="container">
      <h2>Image Upload</h2>
      <div class="form-group">
        <label style="text-align: center;" for="image">Select JPEG Image:</label>
        <div class="file-input-container">
          <label class="file-input-button" for="image">Upload</label>
          <div class="file-input-text">
            <p id="file-text">No File Chosen</p>
          </div>
        </div>
        <input type="file" id="image" accept="image/jpeg" onchange="handleFileSelect(event)">
      </div>
      <p id="message"></p>
      <div style = "margin: 20px 0px 40px 0px;" id="qrcode"></div>
      <p style="text-align: center; margin: 0px;">
        Example of acceptable image name. <b><u>22OC48-1i</u>.jpg</b></p>
      <div id="yes"></div>
    </div>
  </body>
  <script>
    function handleFileSelect(event) 
    {
      const fileInput = event.target;
      const fileNameContainer = document.getElementById('file-text');
      const message = document.getElementById('message');
      const qrDiv = document.getElementById("qrcode");

      if (fileInput.files.length > 0) 
      {
        const file = fileInput.files[0];
        const reader = new FileReader();


        fileNameContainer.innerText = file.name;


        const qrcode = new QRCode("qrcode");
        qrcode.makeCode(file.name.substring(0,7));
        

        reader.onload = function(e) 
        {
          message.innerText = "Uploading Image. Don't Leave";


          const data = {
            name : file.name,
            qrDataUrl : encodeURIComponent(qrDiv.getElementsByTagName("img")[0].src),
            fileDataUrl : e.target.result
          };

          console.log(data.uploadDataURL);

          const xhttp = new XMLHttpRequest();
          xhttp.onreadystatechange = function() 
          {
            if (this.readyState == 4 && this.status == 200) 
            {
              if (this.responseText == 'exists')
              {
                message.innerText = "Cannot Upload Duplicates.";
              }
              else if (this.responseText == 'uploaded')
              {
                document.getElementById('message').innerText = 'Image Was Uploaded';
              }
              else
              {
                document.getElementById('yes').innerHTML = '<img src="'+this.response+'" alt="Image">';
              }
            }
          };
          xhttp.open("POST", "upload.php", true);
          xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
          xhttp.send("URLData=" + JSON.stringify(data));
        }
        setTimeout(function() {
          reader.readAsDataURL(file);
        }, 100);
      } 
      else 
      {
        fileNameContainer.innerText = 'No file chosen';
      }
    }
  </script>
</html>

>Solution :

The src of an img tag must be either a HTTP URL, or a data-url which contains base64-encoded string. But as far as I can see, you appear to be trying to return binary data and set that as the src.

That isn’t how it works. You could set the src as a URL like https://www.example.com/showImage.php?id=123 and that could point to a PHP script which goes and gets the binary data of image number 123 from your database or filesystem, and echoes that data, with a suitable header, and that should work.

So I think you’ve just misunderstood how to set the img tag up correctly.

Leave a ReplyCancel reply