Проверить изображение BLOB-объекта, отправленное ajax - PullRequest
0 голосов
/ 06 сентября 2018

У меня есть обрезчик изображений, который обрезает загруженное изображение, перед отправкой его на сервер с помощью PHP и AJAX.

Вот живая скрипка для предварительного просмотра рабочего примера обрезки. Загрузите изображение, а затем обрежьте его, нажав crop.

Вот код:

// Create cropped part.
function getRoundedCanvas(sourceCanvas) {
  var canvas = document.createElement('canvas');
  var context = canvas.getContext('2d');
  var width = sourceCanvas.width;
  var height = sourceCanvas.height;
  canvas.width = width;
  canvas.height = height;
  context.imageSmoothingEnabled = true;
  context.drawImage(sourceCanvas, 0, 0, width, height);
  context.globalCompositeOperation = 'destination-in';
  context.beginPath();
  context.arc(width / 2, height / 2, Math.min(width, height) / 2, 0, 2 * Math.PI, true);
  context.fill();
  return canvas;
}

// On uploading a file
$("#input").on("change", function(e) {
  var _URL = window.URL || window.webkitURL,
      file = this.files[0],                   
      image = new Image();
  image.src = _URL.createObjectURL(file);    
  image.onload = function(e) {
    var image = document.getElementById('image'),
        button = document.getElementById('button');
    $('#image').attr('src',  _URL.createObjectURL(file));
    $('#image').show();
    $('#button').show();
    var cropper = new Cropper(image, {
      aspectRatio: 1,
      movable: false,
      cropBoxResizable: true,
      dragMode: 'move',
      ready: function () {
        croppable = true;
        button.onclick = function () {
          var croppedCanvas;
          var roundedCanvas;
          var roundedImage;
          if (!croppable) {
            return;
          }
          // Crop
          croppedCanvas = cropper.getCroppedCanvas();
          cropper.getCroppedCanvas({
            fillColor: '#fff',
            imageSmoothingEnabled: true,
            imageSmoothingQuality: 'high',
          });
          // Round
          roundedCanvas = getRoundedCanvas(croppedCanvas);
          // Show
          roundedImage = document.createElement('img');
          roundedImage.src = roundedCanvas.toDataURL();
          result.innerHTML = '';
          result.appendChild(roundedImage);

        }
      }
    });
  }
}); 
#image,
#button{
  display:none
}
<!-- Cropper CSS -->
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.4.1/cropper.min.css">
 
 <!-- Cropper JS -->
 <script src="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.4.1/cropper.min.js"></script>
 
 <!-- File input -->
 <input type="file" id="input" name="image">
 <!-- Selected image will be displayed here -->
 <img id="image" src="" alt="Picture">
 
 <!-- Button to scrop the image -->
 <button type="button" id="button">Crop</button>
 
 <!-- Preview cropped part -->
 <div id="result"></div>

Затем я использую следующий код для отправки blob в PHP с помощью Ajax для сохранения изображения на сервере:

cropper.getCroppedCanvas().toBlob(function (blob) {
  var formData = new FormData();
  formData.append('avatar', blob);
  // Use `jQuery.ajax` method
  $.ajax('upload.php', {
    method: "POST",
    data: formData,
    processData: false,
    contentType: false,
    success: function (response) {
    },
    error: function () {
    }
  });
});

В upload.php:

if( isset($_FILES['avatar']) and !$_FILES['avatar']['error'] ){
  file_put_contents( "uploads/image.png", file_get_contents($_FILES['avatar']['tmp_name']) );
}

Должен ли я сделать некоторые проверки для безопасности или только проверки размеров и размеров?

1 Ответ

0 голосов
/ 06 сентября 2018

Это может быть примером того, как обрабатывать загрузку файла изображения через ваш ajax-вызов к php-скрипту таким образом, который обычно безопасен, а также предотвращает повторные конфликты.

Вам нужно будет придумать свой собственный способ отслеживания имени изображения (используя базу данных или тому подобное), который выходит за рамки вопроса.

Если ваша структура каталогов и php такова:

/path/to/webroot/index.php
/path/to/webroot/upload.php
/path/to/webroot/uploads/(image files)

Следующий PHP для обработки загрузки может быть таким:

upload.php :

<?php
if ( isset($_FILES['avatar']) and empty($_FILES['avatar']['error']) ) {
    if ( is_uploaded_file($_FILES['avatar']['tmp_name']) ) { // safety check

        // validate that it is an accepted image format (and not some junk file)
        $imgdat = getimagesize($_FILES['avatar']['tmp_name']);
        $valid  = array(IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG, IMAGETYPE_BMP);

        if ( in_array($imgdat[2],$valid) ) {
             // create a unique filename for the image, using the extension result
             $imgname = com_create_guid() . image_type_to_extension($imgdat[2]);
             $result  = move_uploaded_file(
                            $_FILES['avatar']['tmp_name'],
                            __DIR__ .'/uploads/'. $imgname
                        ); // safely moves the upload to your final destination
        }

    }
}
else {
    // possible error return handler
}
?>

Если com_create_guid() не существует на вашем сервере, вы можете добавить его в конфигурацию или использовать встроенную мини-функцию для генерации того же: https://stackoverflow.com/a/18206984/2960971

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...