CakePHP 2 не распознает файл, загруженный через ajax

У меня ужасное время, когда я пытаюсь передать файл из представления в контроллер, используя Ajax с CakePHP 2.10.7.

Мой взгляд имеет следующий ввод:

<div id="staff-bg-image-container">
   <!-- Image uploading box exists here. -->
</div>
<input type="file" id="background_image_file" name="background_image_file" style="display:none;" accept="image/png, image/jpeg">

И мой JavaScript выглядит так:

$('#staff-bg-image-container').on('click', () => $('#background_image_file').trigger('click') );
$('#background_image_file').on('change', upload_background);

function upload_background()
{
    var file = this.files[0];    
    data = new FormData();
    data.append('file', file);

    $.ajax({
        url: '/staff/ajaxUploadBackgroundImage',
        type: 'POST',
        data: data,
        contentType: false,
        processData: false,
        cache: false,
        success: function(res){
            console.log(res);
        },
    });
}

Но когда я отправляю этот запрос контроллеру, массив $this->request->data пуст. Я пытался сделать это с помощью XMLHttpRequest вместо jQuery, но результат был таким же. Почему CakePHP не распознает файл?

Изменить: я могу получить доступ к файлу, используя массив глобальных переменных $_FILES. Однако, согласно документации CakePHP, он должен присутствовать в массиве данных запроса. Я был бы признателен, если бы вы могли сказать мне, почему это не так.


person Nadav    schedule 18.02.2020    source источник
comment
Вы добавили enctype='multipart/form-data' в свою форму?   -  person Sehdev    schedule 18.02.2020
comment
@Sehdev Нет формы. Насколько я понимаю, нет необходимости создавать форму, если мне нужно отправить только одно поле.   -  person Nadav    schedule 18.02.2020
comment
Как бы вы выполнили событие изменения, когда элемент не виден style=display:none;??   -  person Sehdev    schedule 18.02.2020
comment
@Sehdev Поскольку пример был связан с работой, я включил только проблемную часть. Извините, если было непонятно. Я обновил свой вопрос, чтобы сделать его менее запутанным. Я могу отправить запрос просто отлично. Но объект запроса CakePHP не включает опубликованный файл.   -  person Nadav    schedule 19.02.2020


Ответы (1)


Что бы я сделал в этом случае, прежде всего, вы пытаетесь загрузить и сохранить только одно событие onchange. В этом случае мой подход состоял бы в том, чтобы создать кнопку, с помощью которой вы будете выполнять событие onclick, чтобы сохранить изображение, которое вы только что загрузили. Поэтому разметка должна быть такой:

  <div id="staff-bg-image-container">
    <img src='/files/<?php echo $data['staff']['background_image_file']; ?>' id="bgimg" class="profile_image" width="450" alt="Image" />
 <!-- Image uploading box exists here. -->
  </div>
 <input type="file" id="background_image_file" name="background_image_file" 
   accept="image/png, image/jpeg"  onchange="readImage(this);"> 
  <button id="saveimg" style="margin-top: 10px;" class="btn-web-admin btn-save 
   upload_img"><?php echo 'Save Image'; ?>
    </button>

Таким образом, ваш Javascript должен выглядеть так:

  function readImage(input) {
    if (input.files && input.files[0]) {
        var reader = new FileReader();               
        reader.onload = function (e) {
                $('#background_image_file').attr('src',e.target.result); // 
               setting ur image here
               $('#saveimg').show();        
       };
       reader.readAsDataURL(input.files[0]);   // Read in the image file as a data URL.             }             
   }
}   

   $('#saveimg').on('click', function(e){
            e.preventDefault();
            var _validFileExtensions = [".jpg", ".jpeg", ".gif", ".png"];
            var validate_img = false;
            var sFileName = $('#background_image_file').val();
            for (var j = 0; j < _validFileExtensions.length; j++){
                var sCurExtension = _validFileExtensions[j];
                if (sFileName.substr(sFileName.length - sCurExtension.length, sCurExtension.length).toLowerCase() == sCurExtension.toLowerCase()) {
                    validate_img = true;
                    break;
                }
            }

            if(validate_img){
                var data = new FormData();
                var file = $('#background_image_file')files[0].;


                data.append('file');
                $.ajax({
                    type: "POST",
                    url: "/staff/ajaxUploadBackgroundImage",
                    data: data,
                    contentType: false,
                    cache: false,
                    processData: false,
                    success: function(data) {
                        var img = new Image();

                         img.onload = function() {
                            var width = img.width;
                            var height = img.height;
                         }
                        img.src = ($('#bgimg')[0]).src;
                    },
                    error: function(a, b, c){
                        console.log('Select a valid image.');
                        console.log(a);
                        console.log(b);
                        console.log(c);
                        return false;
                    }
                });
            }else{
                console.log('Select a valid image.');
            }
    });

Также последний совет, который я хотел бы дать вам, поскольку вы используете FormData, в вашем контроллере вместо $this->request->data, я бы посоветовал вам использовать $this->request->form, поскольку вы предположительно загружаете изображение с запросом Ajax.

     $dataimg = $this->request->form['file']; 
     $this->set('image', $dataimg);

Я надеюсь, что это может помочь вам понять, почему это не работает.

person Oris Sin    schedule 19.02.2020