Отправка данных через xhr.send(finalFiles); и их обработка в php

119
23 мая 2019, 19:10

Есть форма. Большая часть данных с нее собирается и обрабатывается в PHP, кроме одного инпута

<div id="drop-zone"> 
  <p>Перетащите файлы сюда...</p> 
  <div id="clickHere">или нажмите здесь.. 
    <i class="fa fa-upload"></i> 
    <input type="file" name="file[]" id="files" multiple /> 
  </div> 
  <div id='filename'></div> 
</div>

собираю все это в массив (если нужно - могу показать код), массив отправляю таким образом:

var xhr = new XMLHttpRequest(); 
xhr.open('POST', 'http://zayavlenie.com.ua/mail-dev.php', true); 
// The rest of the code will go here... 
// Set up a handler for when the request finishes. 
xhr.onload = function() { 
  if (xhr.status === 200) { 
    // File(s) uploaded. 
    uploadButton.innerHTML = 'Отправка'; 
  } else { 
    alert('An error occurred!'); 
  } 
}; 
console.log(formData); 
console.log(finalFiles); 
xhr.send(finalFiles); 
if (xhr.status != 200) { 
  // обработать ошибку 
  alert(xhr.status + ': ' + xhr.statusText); // пример вывода: 404: Not Found 
} else { 
  alert(xhr.responseText); // responseText -- текст ответа. 
} 
}

На стороне сервера пытаюсь прослушать вообще все что приходит таким образом:

<?
header('Access-Control-Allow-Origin: *');
$post = $_POST;
var_dump($post);
echo('<hr>');
$req = $_REQUEST;
var_dump($req);
echo('<hr>');

На выходе получаю данные с фомры которые обрабатываются php скриптом, но не значение поля input type="file" Массив $_FILES возвращает следующее

array(1) { ["file"]=> array(5) { ["name"]=> array(1) { [0]=> string(0) "" } ["type"]=> array(1) { [0]=> string(0) "" } ["tmp_name"]=> array(1) { [0]=> string(0) "" } ["error"]=> array(1) { [0]=> int(4) } ["size"]=> array(1) { [0]=> int(0) } } } string(0) "" 
Warning: fopen(): Filename cannot be empty in /var/www/zayavlenie/zayavlenie.com.ua/mail-dev.php on line 227
Warning: fread() expects parameter 1 to be resource, boolean given in /var/www/zayavlenie/zayavlenie.com.ua/mail-dev.php on line 228
Warning: fclose() expects parameter 1 to be resource, boolean given in /var/www/zayavlenie/zayavlenie.com.ua/mail-dev.php on line 229

Как правильно отправлять данные при помощи xhr.send()

Answer 1
  1. Со стороны клиента, файлы должны отправляться через объект FormData, это значит что файлы нужно преобразовать, например, вот так:

    var inputElem = document.getElementById('files');  
    var files = inputElem.files;  
    var data = new FormData();  
    Array.from(files).forEach(file => data.append(file.name, file));
    

Проверка наличия элементов в FormData осуществляется методом has (data.has(NAME)), а получение get (data.get(NAME)).

1.2 Отправка данных осуществляется через Content-Type : multipart/form-data (по умолчанию).

var async = true;
var xhr = new XMLHttpRequest();
xhr.open('POST', URL_NAME, async);
xhr.setRequestHeader("Content-Type", "multipart/form-data"); //этот header добавляется по умолчанию
xhr.send(files);

Пример.

var URL_NAME = 'http://zayavlenie.com.ua/mail-dev.php'; 
var async = true; 
 
var inputElem = document.getElementById('files'); 
var ip1 = document.getElementById('ip1'); 
var ip2 = document.getElementById('ip2'); 
 
var data = new FormData(); 
 
function collectFiles() { 
   var files = inputElem.files;   
   Array.from(files).forEach(file => data.append(file.name, file)); 
} 
 
function collectInputs() { 
   data.append('ip1', ip1.value); 
   data.append('ip2', ip2.value); 
} 
 
function send() { 
  var xhr = new XMLHttpRequest(); 
  xhr.open('POST', URL_NAME, async); 
  xhr.send(data); 
} 
 
 
function submit() { 
   collectFiles(); 
   collectInputs(); 
   send(); 
}
<div class="another-inputs"> 
  <input id="ip1" type="text"/> 
  <input id="ip2" type="text"/> 
</div> 
 
<div id="drop-zone"> 
  <p>Перетащите файлы сюда...</p> 
  <div id="clickHere">или нажмите здесь.. 
    <i class="fa fa-upload"></i> 
    <input type="file" name="file[]" id="files" multiple /> 
  </div> 
  <div id='filename'></div> 
   
  <button onClick="submit()">SEND</button> 
</div>

  1. На сервере информацию о файле можно просмотреть в глобальном массиве $_FILES. C механизмом загрузки файлов методом POST можно ознакомиться тут. По сути все сводится к получению названия файла (basename), и его перемещению в существующею директорию (move_uploaded_file)

В Вашем случае файл mail-dev.php будет приблизительно такой.

$uploaddir = '/var/www/uploads/';
foreach ($_FILES as $key => $value) {
    $uploadfile = $uploaddir . basename(value['name']);
    move_uploaded_file(value['tmp_name'], $uploadfile);
    //... + обработка ошибок
}

Итак, что бы отправить файл нужно:
- собрать файлы из формы/инпута;
- преобразовать собранные файлы в объект FormData;
- отправить аякс multipart/form-data;
- на сервере (mail-dev.php) обработать файлы.

READ ALSO
Возможно ли запросом в MySQL выбрать таблицу?

Возможно ли запросом в MySQL выбрать таблицу?

Возможно ли написать SQL-запрос типа "Select table From DBname Where date > '2017-02-11'"? Если да, то как правильно это сормулировать?

153
Получить количество строк по колонке?

Получить количество строк по колонке?

У меня есть таблица orders, в ней у товара есть колонка category_idВопрос, как мне составить запрос наиболее быстрый, чтобы получить все уникальные...

147
Почему не происходит импорт базы данных MySQL через консоль?

Почему не происходит импорт базы данных MySQL через консоль?

Почему верхняя команда не импортирует базу данных, а выдает какую-то помощь?

117
Как настроить отображение блока details-summary?

Как настроить отображение блока details-summary?

У меня в таблице часто используются блоки details-summary

154