Загрузка изображений через API FormData и AJAX не работает ($ФАЙЛЫ всегда пустые)


Когда я пытаюсь сделать то, что указано в названии, все мои запросы работают (проверка проходит без проверки, получен ответ сервера 200, и серверный скрипт также работает должным образом). Моя проблема в том, что я не могу получить доступ к файлу изображения, который я загружаю в скрипт на стороне сервера; $_FILES всегда пуст. Хотя в stack overflow уже есть много сообщений об этом, ни одно из их решений не работает для меня.

Мой HTML (обратите внимание, что я не использую тег формы, но не должен быть проблема):

<input type='file' name='imageupload' id='image-for-upload'>
<button onclick="testAjax()">Launch AJAX Request</button>

Мой JavaScript:

function testAjax() {
  let uploadContainer = document.getElementById('image-for-upload');
  let file = uploadContainer.files[0];
  let data = new FormData();
  data.append("image",file);
  data.append("_ajax_nonce",test_ajax.nonce);
  data.append("action","test_ajax");
  let xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      alert(this.responseText);
    } else {
      console.log(this.status);
    }
  };
  xhttp.open('POST', ajaxurl, true);
  //xhttp.setRequestHeader("Content-type","multipart/form-data");
  xhttp.send(data);
}

Обратите внимание, что я прокомментировал строку setRequestHeader, потому что вместе с ней сервер возвращает ошибку клиента (404) и отвечает "0". Согласно тому, что я обнаружил, это означает, что сервер не понимает механизм действия. При удалении setRequestHeader все работало правильно (за исключением этого вопроса). При проверке заголовка моего HTTP-запроса отправленного запроса я, однако, могу видеть

Content-type: multipart/form-data; boundary=...

...итак для этого заголовка все должно быть в порядке в любом случае.

Мой Серверный скрипт:

<?php
// Ajax script used for testing purposes
check_ajax_referer('ajax-test');
if (empty($_FILES['imageupload'])) {
  echo 'The file is not recognized!';
} else {
  //echo 'it is not working!';
  echo 'It is working!';
}
?>

Что бы я ни делал, я всегда получаю ответ сервера 200, повторяющий "Файл не распознан!". Помочь? (Пожалуйста, придерживайтесь ванильного js, я не хочу кодировать в jQuery).

P.S.: Когда я более точно наблюдаю за своим HTTP-запросом моего ajax-запроса, я вижу, что ниже следующей (первой) его части:

Content-Disposition: form-data; name="image"; filename="myImage.jpg"
Content-Type: image/jpeg

Я получаю довольно длинную супер-странно выглядящую цепочку красных заполненных точек и случайных типы символов, так что, может быть, какая-то кодировка работает неправильно? Или это обычно для органов запроса, отправляющих изображения через данные формы?

Также, когда я использую

var_dump($_POST);

...в качестве ответа сервера в моем серверном скрипте я получаю ассоциативный массив с ключами

[image] => undefined
[_ajax_nonce] => nonce
[action] => test_ajax

..когда я запускаю запрос, не загружая файл в браузер.

Когда я загружаю файл в браузер, а затем запускаю запрос, я получаю ассоциативный массив без [image] => undefined элемент, только последние два, так что, похоже, он не учитывает мое изображение, когда я загрузил одно...?

Author: DevelJoe, 2020-05-22

1 answers

Хорошо, через несколько дней и часов я получил это; моя ошибка заключалась в том, что я попытался получить доступ к загруженному изображению со значением его атрибута name, используя:

$_FILES['imageupload']

По-видимому, когда вы загружаете файл с помощью API FormData, ключ, используемый для доступа к вашему файлу, больше не является значением атрибута name вашего тега input, используемого для загрузки, но он переопределяется ключом, который вы указали в своих formdata соответствующего элемента. Просто говоря, с:

<input type="file" name="imageupload" id="myElement"/>

В вашем HTML-файле (name атрибут фактически устаревает, вам даже не нужно его указывать), и:

myFormData.append('image',file);

В вашем JavaScript вы фактически получаете доступ к своему файлу на PHP на стороне сервера через:

$_FILES['image']

И НЕ с:

$_FILES['imageupload']

Что-то еще. Если сценарий на вашей стороне сервера является php, вы всегда должны указывать файлы данных формы таким образом в JavaScript:

data.append('image[]', file);

И НЕ

data.append('image',file);

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

 0
Author: DevelJoe, 2020-05-22 15:05:29