1

I have this HTML code:

 <div id="container">
   <div id="calendar">
   </div>
 </div>
<button class="btn btn-dark mb-1" onclick="captureAndSave()">Format</button>

And this JS code:

 <script>

  function captureAndSave() 
  {
    // Select "calendar" element
    var elementToCapture = document.querySelector('section.content');

    // Hide ".noPrint" elements
    var elementsToHide = elementToCapture.querySelectorAll('.noPrint');
    elementsToHide.forEach(function(element)
    {
      element.style.visibility = 'hidden';
    });

    html2canvas(elementToCapture).then(function(canvas) 
    {
      var imageBase64 = canvas.toDataURL('image/png');

      elementsToHide.forEach(function(element) 
      {
        element.style.visibility = 'visible';
      });

      var link = document.createElement('a');
      link.href = imageBase64;
      link.download = 'captura.png';

      link.click();
    });
  }

</script> 

Pressing the button is supposed to download an image of the content "section.content", right? Well, this action is actually carried out, but when trying to adapt this code and make it download the image to a server folder instead of being downloaded to the user's computer, I can't do it.

I tried this approach:

<script>

function captureAndSave() 
{
  var elementToCapture = document.querySelector('section.content');

  var elementsToHide = elementToCapture.querySelectorAll('.noPrint');
  elementsToHide.forEach(function (element) {
    element.style.visibility = 'hidden';
  });

  html2canvas(elementToCapture).then(function (canvas) {
    var imageBase64 = canvas.toDataURL('image/png');

    elementsToHide.forEach(function (element) {
      element.style.visibility = 'visible';
    });

    var xhr = new XMLHttpRequest();
    xhr.open('POST', 'assets/imagen.php', true);
    xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');

    var data = 'image=' + encodeURIComponent(imageBase64);
    xhr.send(data);

    xhr.onload = function () {
      if (xhr.status === 200) {
        var response = JSON.parse(xhr.responseText);
        if (response.success) {
          alert(response.message);
        } else {
          alert('Error: ' + response.message);
        }
      }
    };
  });
}

</script>

PHP code called "image.php" that I tried to manage saving to the server without success:

<?php
$response = array();

if(isset($_POST['image'])) 
{
  $imageData = $_POST['image'];

  $filePath = '../vistas/img/temp/imagen.png';

  if(file_put_contents($filePath, base64_decode(preg_replace('#^data:image/\w+;base64,#i', '', $imageData)))) 
  {
    $response['success'] = true;
    $response['message'] = 'The image has been saved successfully.';
  } 
  else 
  {
    $response['success'] = false;
    $response['message'] = 'There was an error saving the image.';
  }
} 
else 
{
  $response['success'] = false;
  $response['message'] = 'No image received.';
}

  header('Content-type: application/json');
  echo json_encode($response);
?>

Any suggestions on what I could change or a better approach to what I want to achieve? First of all, Thanks.

Andrea Duran
  • 180
  • 8
  • Not sure what you're trying to do here, but seeing the preg_replace I remembered https://www.php.net/manual/en/wrappers.data.php which might be of interest for. But honestly, from the question it's not clear to me where your problem stems from, so this must not be the answer. Perhaps add assertions to verify variables contain and functions return what you assume, that could also enable you to point to concrete places in the code you'd like to ask about. – hakre Jul 17 '23 at 20:49

1 Answers1

1

One thing that jumped me is the path defined for your $filePath variable. If the full directory tree where you want to upload your file doesn't exist, the write operation will fail.

You can use the following code to make sure the directory tree up to the file you want to write to exists, before attempting to write to it:

$directory = dirname($filePath);
if (!is_dir($directory)) {
    mkdir($directory, 0777, true);
}

You can also use exception handling to determine what the error is, for debugging purposes. By default, file_put_contents only returns a warning in this situation, so getting PHP to throw exceptions instead may be beyond the scope of your project.

Checking your PHP logs can also help you track down the issue.

Andrei
  • 1,723
  • 1
  • 16
  • 27