Загрузка файлов на сервер php ajax

Загрузка файлов на сервер PHP

Загрузка файлов на сервер php ajax

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

Пример формы:

Форма отправит файл только методом POST и с атрибутом enctype=»multipart/form-data».

Форма для загрузки сразу нескольких файлов:

Файл upload.php:

  • Поддерживает как одиночную загрузку файла так и множественную (multiple) без изменения кода.
  • Проверка на все возможные ошибки которые могут возникнуть при загрузке файлов.
  • Имена файлов переводятся в транслит и удаляются символы которые будут в дальнейшем мешать вывести их на сайте.
  • Есть возможность указать разрешенные и запрещенные для загрузки расширения файлов.

// Название $input_name = 'file'; // Разрешенные расширения файлов. $allow = array(); // Запрещенные расширения файлов. $deny = array( 'phtml', 'php', 'php3', 'php4', 'php5', 'php6', 'php7', 'phps', 'cgi', 'pl', 'asp', 'aspx', 'shtml', 'shtm', 'htaccess', 'htpasswd', 'ini', 'log', 'sh', 'js', 'html', 'htm', 'css', 'sql', 'spl', 'scgi', 'fcgi' ); // Директория куда будут загружаться файлы. $path = __DIR__ . '/uploads/'; if (isset($_FILES[$input_name])) { // Проверим директорию для загрузки. if (!is_dir($path)) { mkdir($path, 0777, true); } // Преобразуем массив $_FILES в удобный вид для перебора в foreach. $files = array(); $diff = count($_FILES[$input_name]) — count($_FILES[$input_name], COUNT_RECURSIVE); if ($diff == 0) { $files = array($_FILES[$input_name]); } else { foreach($_FILES[$input_name] as $k => $l) { foreach($l as $i => $v) { $files[$i][$k] = $v; } } } foreach ($files as $file) { $error = $success = ''; // Проверим на ошибки загрузки. if (!empty($file['error']) || empty($file['tmp_name'])) { switch (@$file['error']) { case 1: case 2: $error = 'Превышен размер загружаемого файла.'; break; case 3: $error = 'Файл был получен только частично.'; break; case 4: $error = 'Файл не был загружен.'; break; case 6: $error = 'Файл не загружен — отсутствует временная директория.'; break; case 7: $error = 'Не удалось записать файл на диск.'; break; case 8: $error = 'PHP-расширение остановило загрузку файла.'; break; case 9: $error = 'Файл не был загружен — директория не существует.'; break; case 10: $error = 'Превышен максимально допустимый размер файла.'; break; case 11: $error = 'Данный тип файла запрещен.'; break; case 12: $error = 'Ошибка при копировании файла.'; break; default: $error = 'Файл не был загружен — неизвестная ошибка.'; break; } } elseif ($file['tmp_name'] == 'none' || !is_uploaded_file($file['tmp_name'])) { $error = 'Не удалось загрузить файл.'; } else { // Оставляем в имени файла только буквы, цифры и некоторые символы. $pattern = «[a-zа-яё0-9,~!@#%-_\$\?\(\)\{\}\[\]\.]»; $name = mb_eregi_replace($pattern, '-', $file['name']); $name = mb_ereg_replace('[-]+', '-', $name); // Т.к. есть проблема с кириллицей в названиях файлов (файлы становятся недоступны). // Сделаем их транслит: $converter = array( 'а' => 'a', 'б' => 'b', 'в' => 'v', 'г' => 'g', 'д' => 'd', 'е' => 'e', 'ё' => 'e', 'ж' => 'zh', 'з' => 'z', 'и' => 'i', 'й' => 'y', 'к' => 'k', 'л' => 'l', 'м' => 'm', 'н' => 'n', 'о' => 'o', 'п' => 'p', 'р' => 'r', 'с' => 's', 'т' => 't', 'у' => 'u', 'ф' => 'f', 'х' => 'h', 'ц' => 'c', 'ч' => 'ch', 'ш' => 'sh', 'щ' => 'sch', 'ь' => '', 'ы' => 'y', 'ъ' => '', 'э' => 'e', 'ю' => 'yu', 'я' => 'ya', 'А' => 'A', 'Б' => 'B', 'В' => 'V', 'Г' => 'G', 'Д' => 'D', 'Е' => 'E', 'Ё' => 'E', 'Ж' => 'Zh', 'З' => 'Z', 'И' => 'I', 'Й' => 'Y', 'К' => 'K', 'Л' => 'L', 'М' => 'M', 'Н' => 'N', 'О' => 'O', 'П' => 'P', 'Р' => 'R', 'С' => 'S', 'Т' => 'T', 'У' => 'U', 'Ф' => 'F', 'Х' => 'H', 'Ц' => 'C', 'Ч' => 'Ch', 'Ш' => 'Sh', 'Щ' => 'Sch', 'Ь' => '', 'Ы' => 'Y', 'Ъ' => '', 'Э' => 'E', 'Ю' => 'Yu', 'Я' => 'Ya', ); $name = strtr($name, $converter); $parts = pathinfo($name); if (empty($name) || empty($parts['extension'])) { $error = 'Недопустимое тип файла'; } elseif (!empty($allow) && !in_array(strtolower($parts['extension']), $allow)) { $error = 'Недопустимый тип файла'; } elseif (!empty($deny) && in_array(strtolower($parts['extension']), $deny)) { $error = 'Недопустимый тип файла'; } else { // Чтобы не затереть файл с таким же названием, добавим префикс. $i = 0; $prefix = ''; while (is_file($path . $parts['filename'] . $prefix . '.' . $parts['extension'])) { $prefix = '(' . ++$i . ')'; } $name = $parts['filename'] . $prefix . '.' . $parts['extension']; // Перемещаем файл в директорию. if (move_uploaded_file($file['tmp_name'], $path . $name)) { // Далее можно сохранить название файла в БД и т.п. $success = 'Файл «' . $name . '» успешно загружен.'; } else { $error = 'Не удалось загрузить файл.'; } } } // Выводим сообщение о результате загрузки. if (!empty($success)) { echo '

' . $success . '

'; } else { echo '

' . $error . '

'; } } }

Загрузка файлов через AJAX

Файлы можно отправить без перезагрузки страницы с помощью jQuery Form Plugin.

Как это работает:

  1. На поле выбора файла с id=»js-file» повешено jquery событие change.
  2. При выборе файла срабатывает событие и выполняется метод плагина ajaxSubmit, он все поля из формы с id=»js-form» включая выбранный файл отправляет на uploads.php.
  3. Далее то что отдаст uploads.php выведется в ….
  4. После завершения, форма очищается методом reset() т.к. input file останется с выбранным файлом.

Возможные проблемы

  • На unix хостингах php функция move_uploaded_file() не будут перемещать файлы в директорию если у нее права меньше 777.
  • Загрузка файлов может быть отключена в настройках PHP директивой file_uploads.
  • Не загружаются файлы большого размера, причина в ограничениях хостинга. Посмотрите в phpinfo() значения директив:
    • upload_max_filesize – максимальный размер закачиваемого файла.
    • max_file_uploads – максимальное количество одновременно закачиваемых файлов.
    • post_max_size – максимально допустимый размер данных, отправляемых методом POST, его значение должно быть больше upload_max_filesize.
    • memory_limit – значение должно быть больше чем post_max_size.

Источник: https://snipp.ru/view/115

Как создать загрузчик файлов в стиле Ajax

Загрузка файлов на сервер php ajax

Choose file(s) to upload:

Loading, please wait…

      Ajax Uploader        

  $(document).ready(function() {  var upload = new AjaxUpload('#userfile', {          //action: 'upload.php', //выгружает отключенное в целях безопасности          onSubmit : function(file, extension){          //показываем анимацию загрузки          //проверяем расширение файла          if (! (extension && /(jpg|png|jpeg|gif)$/.test(extension))){         // расширение не разрешено               $(«Error: Not a valid file extension»).appendTo(«#file_holder #errormes»);                // избавляемся от сообщения об ошибке              upload.setData({'file': file});          onComplete : function(file, response){          //скрываем анимацию загрузки          //добавляем display:block в держатель сообщения о выполнении          $(«.success»).css(«display», «block»);          //находим div в iFrame и прикрепляем к сообщению об ошибке          var oBody = $(«.iframe»).contents().find(«div»);          //добавляем iFrame к errormes td          $(oBody).appendTo(«#file_holder #errormes»);  

Шаг 4: PHP

Файл php делает действительную выгрузку на наш сервер в то время, как функции, которые мы приведем в исполнение, обеспечивают валидацию, чтобы убедиться, что выгруженный файл остается в пределах установленных нами правил. Объяснить все проще поможет разбиение этого файла на секции.

$max_filesize = 2097152; // максимальный размер файла в БАЙТАХ. $allowed_filetypes = array('.jpg','.jpeg','.gif','.png'); // Это будут виды файлов, которые пройдут проверку (валидацию). $filename = $_FILES['userfile']['name']; // получаем название файла (включая его расширение). $ext = substr($filename, strpos($filename,'.'), strlen($filename)-1); // Получаем расширение из названия файла. $file_strip = str_replace(» «,»_»,$filename); //Замещаем пробелы в названии файла $upload_path = '/path/to/uploads/'; //устанавливаем путь выгрузки

$max_filesize = 2097152; // максимальный размер файла в БАЙТАХ.  $allowed_filetypes = array('.jpg','.jpeg','.gif','.png'); // Это будут виды файлов, которые пройдут проверку (валидацию).  $filename = $_FILES['userfile']['name']; // получаем название файла (включая его расширение).  $ext = substr($filename, strpos($filename,'.'), strlen($filename)-1); // Получаем расширение из названия файла.  $file_strip = str_replace(» «,»_»,$filename); //Замещаем пробелы в названии файла  $upload_path = '/path/to/uploads/'; //устанавливаем путь выгрузки

Хотя многое тут и так понятно, я поясню, что выполняет все вышеприведенное.

JavaScript. Быстрый старт

Изучите основы JavaScript на практическом примере по созданию веб-приложения

Узнать подробнее

Переменная $max_filesize определяет максимальный размер разрешенного для выгрузки файла, в данный момент она установлена на 2mb (так по умолчанию выставляют свои серверы большинство хостинг-провайдеров), определенные в байтах.

Переменная $filename получает из ввода #userfile название файла целиком, включая расширение.
Переменная $ext проверяет правильность расширения на соответствие массиву $allowed_filetypes.

Переменная $allowed_filetypes выстраивает и располагает в определенном порядке виды файлов для ссылки, когда запускается проверка в нижней части кода, до которого мы вскоре доберемся.

$file_strip замещает любые пробелы в названии файла подчеркиваниями, зачем? Если имя файла используется в url, таком как ссылка на изображение и т.д., пробелы часто замещаются на 20% созданием адреса sloppy и его сложно индексировать поисковикам.

Наконец, $upload_path определяет папку, в которую будут перемещаться выгрузки, соответствующую домашней на вашем сервере. Другими словами, большинство серверов конфигурируются файловой структурой вроде этой:/home/yourusername/yoursite.com/path/to/uploads/. Убедитесь, что используете полный путь с начальными и конечными метками «/».

Находим корневой каталог сервера

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

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

// Проверяем, разрешен ли тип файла, если не DIE, и информируем пользователя. if(!in_array($ext,$allowed_filetypes)) { die('Загружаемый тип файла недостим.'); }

// Проверяем, разрешен ли тип файла, если не DIE, и информируем пользователя.   if(!in_array($ext,$allowed_filetypes)) {    die('Загружаемый тип файла недостим.');  

Вначале проверяется массив видов файлов, и если данного расширения в нем нет, скрипт останавливает выполнение (die) и выводит сообщение об ошибке.

// Теперь проверяем размер файла, если он слишком большой, то DIE и информируем пользователя. if(filesize($_FILES['userfile']['tmp_name']) > $max_filesize) { die('Загружаемы файл слишком большой.'); }

// Теперь проверяем размер файла, если он слишком большой, то DIE и информируем пользователя.    if(filesize($_FILES['userfile']['tmp_name']) > $max_filesize) {       die('Загружаемы файл слишком большой.');  

Проверьте размер файла на соответствие установленной переменной, если он больше, скрипт останавливает выполнение (die) и выводит сообщение об ошибке.

// Проверяем, можно ли выгрузить в определенный путь, если нет, то DIE и информируем пользователя. if(!is_writable($upload_path)) { die('Вы не можете загружать в папку /uploads/. Измените права на папку.');

// Проверяем, можно ли выгрузить в определенный путь, если нет, то DIE и информируем пользователя.   if(!is_writable($upload_path)) {      die('Вы не можете загружать в папку /uploads/. Измените права на папку.');  

Эта часть кода проверяет папку на сервере, чтобы убедиться, что она перезаписываемая, или пригодна для размещения в ней файла нашим скриптом. Если нет, снова применяем (die) и выводим сообщение пользователю.

// Перемещаем файл, если все прошло проверку. if(move_uploaded_file($_FILES['userfile']['tmp_name'],$upload_path . $file_strip)) { echo ''. $file_strip .' Файл успешно загружен.'; // Получилось. } else { echo ''. $file_strip .' Файл не загружен. Попробуйте позже.>'; // Не получилось :(. }

// Перемещаем файл, если все прошло проверку.    if(move_uploaded_file($_FILES['userfile']['tmp_name'],$upload_path . $file_strip)) {       echo ''. $file_strip .' Файл успешно загружен.'; // Получилось.       echo ''. $file_strip .' Файл не загружен. Попробуйте позже.>'; // Не получилось :(.  

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

upload.php

Скопируйте и вставьте весь этот код в новый файл и сохраните его как upload.php

Источник: https://webformyself.com/kak-sozdat-zagruzchik-fajlov-v-stile-ajax/

Валидация и отправка файлов на сервер с помощью ajax

Загрузка файлов на сервер php ajax

Сегодня я хочу рассказать, как отправить файлы на сервер из html-формы. Обычно эта процедура не вызывает никаких затруднений: кодировка multipart/form-data у формы, input type=»file» и все. Остается принять файлы на сервере и скопировать их в нужное место.

Но мы сделаем интереснее, отправим файлы с помощью ajax, без перезагрузки страницы. А также посмотрим, как валидировать файлы на клиенте и сервере, а именно проверять максимальный размер загружаемых файлов и допустимые расширения.

Суть задачи

По итогу статьи у нас получится небольшое приложение, которое отрисует форму с тремя полями ввода и кнопкой Отправить. Будем считать, что мы хотим получить от пользователей три файла-картинки. При этом нужно задать максимальный размер загружаемых файлов и ограничить набор расширений. Проверять файлы нужно как на клиенте, для удобства пользователей, так и на сервере, для защиты от возможных атак. Если обе проверки пройдены, то скопируем файлы на сервере в папку upload.

Для нетерпеливых сразу ссылки на демо приложения и исходники

Подготовим шаблон проекта.

В корень проекта положим файл index.html, в папку js файлы jquery.min.js и main.js (не забудем их подключить в index.html). Серверный код будет выполнять upload.php из папки php, а для полученных файлов создадим папку upload.

Получится так:

html-заготовка формы

Создадим простейшую форму в index.html

Заметим, что никаких атрибутов, вроде enctype у формы или name у input-ов, навешивать не нужно — все сделает javascript.

Базовый клиентский код

'use strict'; // Модуль приложения var app = (function($) { // Отправка формы function submitForm(e) { e.preventDefault(); var $photos = $('.js-photos'), formdata = new FormData; // Добавление файлов в formdata $photos.each(function(index, $photo) { if ($photo.files.length) { formdata.append('photos[]', $photo.files[0]); } }); // Отправка на сервер $.ajax({ url: 'php/upload.

php', data: formdata, type: 'POST', dataType: 'json', processData: false, contentType: false, success: function(responce) { console.log('responce from server: ', responce); } }); } // Инициализация function init() { $('#main-form').on('submit', submitForm); } return { init: init } })(jQuery); // Запуск приложения jQuery(document).ready(app.

init);

Мы создали модуль приложения app, и в методе init подключили обработку сабмита формы. В функции submitForm данные для отправки готовятся с помощью объекта formdata соответствующего класса FormData. Перебирая все поля выбора файлов .js-photos, мы добавляем файлы к этому объекту методом append.

Обратите внимание на название photos[] — квадратные скобки обязательны, так как в противном случае на сервер попадет не массив файлов, а только один.

Дальше в настройках метода $.ajax указываем стандартные параметры url, data и type. Отправляем данные, конечно, POST-ом. processData и contentType нужно отключить. Поставим dataType = «json», так как именно в этом формате сервер будет возвращать ответ.

multipart/form-data опять не указывается явно, потому что она проставляется сама при использовании объекта FormData. Разумеется, кроме файлов Вы можете отправить и еще какие угодно данные, добавив их в formdata, например так: formdata.

append('name', 'John');

Валидацию пока не делаем, рассмотрим ее ниже. А пока переходим к серверной части.

Принимаем файлы на сервере и перемещаем в нужную папку

Код обработки файлов на сервере довольно типовой, сначала привожу его, а потом кратко поясню

$photos = $_FILES['photos']; $destPath = $_SERVER['DOCUMENT_ROOT'] . '/upload/'; // Копирование файлов в нужную папку foreach ($photos['name'] as $key => $name) { $tempName = $photos['tmp_name'][$key]; $destName = $destPath . $name; move_uploaded_file($tempName, $destName); } // Возвращаем ответ клиенту echo json_encode(array( 'code' => 'success' ));

Сначала мы извлекаем массив файлов из $_FILES['photos'] и отпределяем папку назначения — куда мы копируем искомые файлы. PHP предварительно копирует файлы во временную папку, свойство tmp_name из $_FILES даст нам полный путь к этому временному файлу. Далее перебираем наш массив и перемещаем файлы в нужную папку под тем же названием, с которым он пришел с клиента. Этим занимается функция move_uploaded_file. В конце возвращаем клиенту успешный код ответа.

В принципе, чтобы просто отправить файлы на сервер, приведенного кода достаточно. Но при этом у нас нет никаких средств для проверки правильности выбранных файлов и защиты от атак. Поэтому дальше займемся валидацией файлов на клиенте и сервере. Начнем с клиента.

Валидация файлов на клиенте

Нам нужна функция, которая проверит массив файлов с формы на некоторые условия, а именно:

  • 1. Выбран ли вообще файл
  • 2. Не превышает ли его размер максимальный
  • 3. Подходит ли файл по формату

Если какие-то условия не выполняются, то будем складывать в массив имя файла, в котором произошла ошибка, и указывать код ошибки. Дополнительно укажем, в каком по счету элементе input ошибка.

Например, ошибка может выглядеть так.

{ index: 0, name: 'test.pdf', errorCode: 'wrong_type' }

Это означает, что в input[0] (в первом по счету поле) пользователь добавил файл test.pdf, формат которого не поддерживается, так как мы просим изображения. Это одна ошибка валидации. А массив таких ошибок и будет результатом выполнения функции. Если ошибок нет, все файлы выбраны и заданы правильно, то вернем пустой массив.

Впрочем, сейчас посмотрим, как это работает. Добавим функцию валидации validateFiles.

// Валидация файлов function validateFiles(options) { var result = [], file; // Перебираем файлы options.$files.each(function(index, $file) { // Выбран ли файл if (!$file.files.length) { result.push({index: index, errorCode: 'no_file'}); // Остальные проверки не имеют смысла, переходим к следующему файлу return; } file = $file.files[0]; // Проверяем размер if (file.size > options.maxSize) { result.push({index: index, name: file.name, errorCode: 'big_file'}); } // Проверяем тип файла if (options.types.indexOf(file.type) === -1) { result.push({index: index, name: file.name, errorCode: 'wrong_type'}); } }); return result; }

В параметре options мы передаем объект из трех полей: $files, maxSize и types. Соответственно, это jQuery-массив элементов input, максимальный размер файла в байтах и массив допустимых типов-расширений файлов, например, image/jpg, image/png или application/pdf — список типов легко можно загуглить.

Мы перебираем массив файлов и последовательно делаем проверки. Сначала смотрим, выбран ли вообще файл. Если нет, добавляем в результирующий массив ошибок пукнт с кодом no_file. Это будет объект-ошибка {index: index, errorCode: 'no_file'} — имени предсказуемо нет. Дальше мы сразу переходим к следующему файлу, проверит размер и расширение мы не сможем.

Проверка на максимальный размер в случае неуспеха вернет объект {index: index, name: file.name, errorCode: 'big_file'}, а несоответствие типа — {index: index, name: file.name, errorCode: 'wrong_type'}

Обратите внимание, если в одном файле ловится несколько ошибок (максимум две в нашем случае), например, test.pdf слишком большого веса, то в результате мы получим 2 объекта. Имеет смысл группировать эти ошибки по имени файла, но не хочется усложнять код. В конце концов, если это необходимо, Вы сможете обработать выводимый результат как угодно.

Функцию написали, осталось задействовать ее в основном потоке кода. Немного расширим код submitForm:

// Отправка формы function submitForm(e) { e.preventDefault(); var $photos = $('.js-photos'), formdata = new FormData, validationErrors = validateFiles({ $files: $photos, maxSize: 2 * 1024 * 1024, types: ['image/jpeg', 'image/jpg', 'image/png'] }); // Валидация if (validationErrors.length) { console.log('client validation errors: ', validationErrors); return false; } // Добавление файлов в formdata … // Отправка на сервер … }

Как видим, мы добавили вызов validateFiles с нужными параметрами. Максимальный размер файла ограничим 2 Мб, а типы возьмем jpg и png-картинки. После вызова проверяем, не пустой ли массив полученных ошибок, и если таки не пустой, то выводим результаты в консоль и выходим из функции сабмита. Файлы на сервер не уйдут.

Как обрабатывать ошибки и показывать их пользователю — дело исключительно хозяйское 🙂 Нам сейчас главное убедиться, что наша валидация работает.

Клиенсткий код закончен, можете побаловаться с файлами, добавить или убрать форматы разрешенных типов или изменить максимальный размер. Наш клиентский код должен точно реагировать на все попытки загрузить «неправильные» файлы. А мы переходим к валидации на стороне сервера.

Валидация файлов на сервере

Вообще для посетителей сайта будет срабатывать клиентская валидация. Тем самым наши посетители получат мгновенную обратную связь, а сервер освободится от ненужной работы. Но в случае получения пользовательских данных всегда нужно проводить дополнительную валидацию на стороне сервера. Этим мы и займемся.

php-шная функция валидации будет проверять ровно те же параметры, что и клиентская. Но кроме двух пунктов: проверки на наличие файла и возврат индекса. Это связано с тем, что мы проверяем все файлы пришедшие с клиента и не знаем, что некоторые клиент мог не заполнить. Лучше увидеть на примере. Напишем саму функцию

// Валидация файлов function validateFiles($options) { $result = array(); $files = $options['files']; foreach ($files['tmp_name'] as $key => $tempName) { $name = $files['name'][$key]; $size = filesize($tempName); $type = $files['type'][$key]; // Проверяем размер if ($size > $options['maxSize']) { array_push($result, array( 'name' => $name, 'errorCode' => 'big_file' )); } // Проверяем тип файла if (!in_array($type, $options['types'])) { array_push($result, array( 'name' => $name, 'errorCode' => 'wrong_type' )); } } return $result; }

Обращаю внимание, что для синхронизации клиента и сервера в обеих функциях валидации используется одинаковый формат объекта-ошибки и коды ошибок. Это облегчит нам обработку ошибок в интерфейсе независимо от того, сработала ли валидация клиентская или серверная.

После этого остается использовать написанную функцию в основном коде

$photos = $_FILES['photos']; $destPath = $_SERVER['DOCUMENT_ROOT'] . '/upload/'; // Валидация $validationErrors = validateFiles(array( 'files' => $photos, 'maxSize' => 2 * 1024 * 1024, 'types' => array('image/jpeg', 'image/jpg', 'image/png') )); if (count($validationErrors) > 0) { // Возвращаем список ошибок клиенту echo json_encode($validationErrors); exit; } // Копирование файлов в нужную папку … // Возвращаем ответ клиенту echo json_encode(array( 'code' => 'success' ));

Вот и все. Как видим, валидация на сервере подключена ровно таким же способом, как и на клиенте.

Чтобы убедиться, что и серверная валидация успешно работает, закомментируйте одну строку в main.js

if (validationErrors.length) { console.log('client validation errors: ', validationErrors); // return false; }

Теперь попробуйте ввести в форму ошибочные данные и увидите, что в консоли выпадет сообщение «client validation errors:» с массивом ошибок от клиентской валидации, а следом «responce from server:» с ошибками от серверной. Ошибки должны быть совершенно идентичными, за исключением no_file на клиенте и отсутствия поля index на сервере.

Например, если Вы пропустите первое поле, во второе загрузите pdf-ку, а в третье — валидную картинку, то увидите примерно такую картину

Ссылки и исходники

Демо приложения
Скачать исходники

Источник: https://webdevkin.ru/posts/raznoe/otpravka-fajlov-na-server-ajax

Ajax и PHP. Загрузка изображения на сервер

Загрузка файлов на сервер php ajax

В наше время веб-сайты становятся все более интерактивными. Это касается не только специализированных сервисов, но и обычных интернет магазинов, блогов и небольших сайтов.

Основной особенностью является асинхронный JavaScript и XML сокращенно AJAX. Эта технология позволяет браузеру в фоновом режиме общаться с веб-сервером и при обновлении данных, веб-страница не перезагружается полностью.

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

Поскольку наиболее популярным языком для разработки веб-приложений является PHP, то сегодня мы будем использовать связку AJAX и PHP. Пример будет хорош для понимания основных принципов работы с AJAX и PHP.

На самом деле особых сложностей быть не должно, алгоритм действий:

  • Выбрать картинку
  • Нажать кнопку “Отправить”
  • Перехватить вызов формы с помощью JavaScript (jQuery)
  • Передать содержимое в специальный php скрипт-обработчик
  • Вернуть результат выполнения
  • Обработать результат при помощи JavaScript (jQuery)
  • Вывести пользователю информацию о загрузке

Кратко о jQuery и AJAX

Немного отклонюсь от темы и объясню что такое jQuery. jQuery — это специальная JavaScript библиотека, которая помогает упростить разработку веб приложений в несколько раз, также данная библиотека предоставляет API для работы с AJAX. Простыми словами, мы напишем меньше кода, чем если бы это делали на чистом JS.

Ajax позволяет не перезагружая веб-страницу, обмениваться данными с веб-сервером и обновлять ее содержимое.

Я склоняюсь к тому, что если есть инструмент, который позволяет вам ускорить разработку без последствий, то почему бы его не использовать? Но чистый JS тоже не помешало бы знать(хоть и лично мой уровень владения JS равен уровню копипаста примеров со stackoverflow

Источник: https://adminnotes.info/%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5/ajax-and-php.html

Красивая AJAX форма для загрузки файлов

Загрузка файлов на сервер php ajax

В этом уроке мы сделаем небольшую AJAX форму для загрузки файлов, которая позволит посетителям загружать файлы с помощью технологии drag/drop или при помощи обычного выбора файлов.

Мы будем использовать плагины jQuery File Upload и  jQuery Knob для отображения прогресса загрузки.

Т.к. форма будет иметь возможность загружать файлы двумя способами, она будет работать даже если drag/drop не поддерживается.

HTML

Как обычно, начнем с HTML5 разметки:

Drop Here Browse

В теге нашего документа, подключаем шрифты Google Webfonts, а перед закрытием тега  — JavaScript библиотеки:  jQuery, jQuery Knob и jQuery File Upload.

Главный элемент страницы — форма #upload. Внутри нее элемент #drop (принимает файлы с использованием drag&drop)   и список, в котором будут отображаться загружаемые файлы. Разметка, которая будет генерироваться для загруженных файлов:

  • Sunset.jpg 145 KB

  • Элемент input будет спрятан с помощью CSS. Он нужен для инициализации плагина jQuery Knob, который будет рисовать шкалу процесса загрузки файла.  Input имеет атрибуты data-*, которые используются для обновления шкалы. Позже, когда мы будет отслеживать прогресс загрузки, мы будем обновлять эти значения для перерисовки шкалы. span будет содержать зеленую галку или красный крест.

    jQuery

    У посетителя будет 2 способа загрузки файла:

    • Перетащить файл в окно браузера (в IE не работает).
    • Нажатием на кнопку browse. Будет имитировано нажатие на спрятанный input и показано системное окно выбора файлов. Обратите внимание, что input имеет параметр multiple параметр, что позволит выбирать много файлов за один раз.

    Когда файлы будут выбраны, они помещаются в очередь для последующей автоматической загрузки:

    $(function(){ var ul = $('#upload ul'); $('#drop a').click(function(){ // имитация нажатия на поле выбора файла $(this).parent().find('input').click(); }); // инициализация плагина jQuery File Upload $('#upload').fileupload({ // этот элемент будет принимать перетаскиваемые на него файлы dropZone: $('#drop'), // Функция будет вызвана при помещении файла в очередь add: function (e, data) { var tpl = $(''); // вывод имени и размера файла tpl.find('p').text(data.files[0].name) .append('' + formatFileSize(data.files[0].size) + ''); data.context = tpl.appendTo(ul); // инициализация плагина jQuery Knob tpl.find('input').knob(); // отслеживание нажатия на иконку отмены tpl.find('span').click(function(){ if(tpl.hasClass('working')){ jqXHR.abort(); } tpl.fadeOut(function(){ tpl.remove(); }); }); // Автоматически загружаем файл при добавлении в очередь var jqXHR = data.submit(); }, progress: function(e, data){ // Вычисление процента загрузки var progress = parseInt(data.loaded / data.total * 100, 10); // обновляем шкалу data.context.find('input').val(progress).change(); if(progress == 100){ data.context.removeClass('working'); } }, fail:function(e, data){ // что-то пошло не так data.context.addClass('error'); } }); $(document).on('drop dragover', function (e) { e.preventDefault(); }); // вспомогательная функция, которая форматирует размер файла function formatFileSize(bytes) { if (typeof bytes !== 'number') { return ''; } if (bytes >= 1000000000) { return (bytes / 1000000000).toFixed(2) + ' GB'; } if (bytes >= 1000000) { return (bytes / 1000000).toFixed(2) + ' MB'; } return (bytes / 1000).toFixed(2) + ' KB'; } });

    В jQuery File Upload есть собственный интерфейс, но мы используем базовую версию плагина для создания собственного дизайна интерфейса. И чтобы наш интерфейс работал, мы передаем плагину несколько параметров / колбэков:

    • dropZone – этот параметр содержит jQuery селектор, который будет принимать перетаскиваемые файлы. Файлы, брошенные на него, будут добавлены в очередь загрузки.
    • add – функция вызывается при добавлении файла в очередь загрузки. Она будет генерировать разметку для файлов и вызвать метод data.submit().
    • progress – Эта функция будет вызываться каждые 100ms (можно изменить). Второй аргумент содержит размер файла и количество загруженных байт. Это позволяет отслеживать прогресс и обновлять шкалу.
    • fail – функция вызывается при возникновении ошибки.

    PHP

    В комплект jQuery File Upload входит также и PHP скрипт для обработки файлов на сервере, но мы напишем свой. Процесс загрузки фалов будет происходить также как и при обычной загрузке, поэтому всю информацию о них мы можем получить из глобального массива $_FILES:

    Источник: http://easy-code.ru/lesson/ajax-file-upload-form

    Загрузка файлов (картинок) на сервер через AJAX и jQuery

    Загрузка файлов на сервер php ajax

    Как загружать любые файлы, например, картинки на сервер с помощью AJAX и jQuery? Делается это довольно просто! И ниже мы все обстоятельно разберем.

    В те «древние» времена, когда еще не было jQuery, а может он был, но браузеры были не так наворочены, загрузка файла на сайт с помощью AJAX была делом муторным: через всякие костыли вроде iframe. Я те время не застал, да и кому это теперь интересно. А интересно теперь другое — что сохранение файлов на сайт делается очень просто.

    Даже не обладающий опытом и пониманием, того как работает AJAX, вебмастер, сможет быстро разобраться что-куда. А эта статья ему в помощь. Если подкрепить эти возможности функциями WordPress, то безопасная обработка и загрузка файлов на сервер становится совсем плевым и даже интересным делом (пример с WordPress смотрите в конце статьи).

    Однако, как бы все просто не было, нужно заметить, что минимальный опыт работы с файлами и базовые знания в Javascript, jQuery и PHP все же необходимы! Минимум, нужно представлять как загружаются файлы на сервер, как в общих чертах работает AJAX и хоть немного надо уметь читать и понимать код.

    Описанный ниже метод довольно стабилен, и по сути опирается на Javascript объект new FormData(), базовая поддержка которого есть во всех браузерах.

    Для более понятного восприятия материала, он разделен на шаги. На этом все, полетели…

    плагин для упрощения работы с AJAX в WordPress.

    AJAX Загрузка файлов: общий пример

    Начинается все с наличия на сайте input поля типа file. Нет необходимости, чтобы это поле было частью формы (тега ).

    Таким образом, у нас есть HTML код с file полем и кнопкой «Загрузить файлы».

    Загрузить файлы

    Шаг 1. Данные из поля file

    Первым шагом, нужно получить данные загружаемых файлов.

    При клике на file-поле, появляется окно выбора файлов, после выбора, данные о них сохраняются в input поле, а нам нужно их от туда «забрать». Для этого повесим на событие change JS функцию, которая будет сохранять имеющиеся данные file-поля в JS переменную files:

    var files; // переменная. будет содержать данные файлов // заполняем переменную данными, при изменении значения поля file $('input[type=file]').on('change', function(){ files = this.files;});

    Шаг 2. Создаем AJAX запрос (по клику)

    Данные файлов у нас есть, теперь их нужно отправить через AJAX. Вешаем это событие на клик по кнопке «Загрузить файлы».

    В момент клика создаем новый объект new formData() и добавляем в него данные из переменной files. С помощью formData() мы добьемся того, что отправляемые данные будут выглядеть, как если бы мы просто сабмитили форму в браузере.

    Далее, из имеющихся данных формы создаем нестандартный AJAX запрос, в котором передаем файлы в стандартном для сервера формате: $_FILES.

    Чтобы такой запрос состоялся, в jQuery нужно указать дополнительные AJAX параметры, поэтому привычная функция $.post() не подходит и мы используем более гибкий аналог: $.ajax().

    Два важных дополнительных параметра нужно установить в false:

    processDataОтключает обработку передаваемых данных. По умолчанию, например, для GET запросов jQuery собирает данные в строку запроса и добавляет эту строку в конец URL. Для POST данных делает другие преобразования. Нам любые изменения исходных данных будут мешать, поэтому отключаем эту опцию…contentTypeОтключает установку заголовка типа запроса. Дефолтная установка jQuery равна «application/x-www-form-urlencoded. Такой заголовок не предусматривает отправку файлов. Если установить этот параметр в «multipart/form-data», PHP все равно не сможет распознать передаваемые данные и выведет предупреждение «Missing boundary in multipart/form-data»… В общем, проще всего отключить эту опция, тогда все работает!// обработка и отправка AJAX запроса при клике на кнопку upload_files$('.upload_files').on( 'click', function( event ){ event.stopPropagation(); // остановка всех текущих JS событий event.preventDefault(); // остановка дефолтного события для текущего элемента — клик для тега // ничего не делаем если files пустой if( typeof files == 'undefined' ) return; // создадим объект данных формы var data = new FormData(); // заполняем объект данных файлами в подходящем для отправки формате $.each( files, function( key, value ){ data.append( key, value ); }); // добавим переменную для идентификации запроса data.append( 'my_file_upload', 1 ); // AJAX запрос $.ajax({ url : './submit.php', type : 'POST', // важно! data : data, cache : false, dataType : 'json', // отключаем обработку передаваемых данных, пусть передаются как есть processData : false, // отключаем установку заголовка типа запроса. Так jQuery скажет серверу что это строковой запрос contentType : false, // функция успешного ответа сервера success : function( respond, status, jqXHR ){ // ОК — файлы загружены if( typeof respond.error === 'undefined' ){ // выведем пути загруженных файлов в блок '.ajax-reply' var files_path = respond.files; var html = ''; $.each( files_path, function( key, val ){ html += val +'
    '; } ) $('.ajax-reply').html( html ); } // ошибка else { console.log('ОШИБКА: ' + respond.error ); } }, // функция ошибки ответа сервера error: function( jqXHR, status, errorThrown ){ console.log( 'ОШИБКА AJAX запроса: ' + status, jqXHR ); } }); }); меню

    Шаг 3. Обрабатываем запрос: загружаем файлы на сервер

    Теперь последний шаг: нужно обработать отправленный запрос.

    Чтобы было наглядно обработаем запрос без дополнительных проверок для файлов, т.е. просто сохраним полученные файлы в нужную папку. Хотя, для безопасности, отправляемые файлы обязательно нужно проверять, хотя бы расширение (тип) файла…

    Создадим файл submit.php с таким кодом (предполагается что submit.php лежит в той же папке, где и файл, с которого отправляется AJAX запрос):

    Источник: https://wp-kama.ru/id_9026/jquery-ajax-zagruzka-fajlov-na-server.html