Загрузка файлов на сервер с помощью ajax

  • 18.06.2019

Добрый день!

Долгое время на просторах интернета я искал информацию о реализации AJAX загрузки файлов для CodeIgniter. Разные разработчики предлагали разные технологии и примеры реализации. Я перепробовал их все, но ни одна из них не была достаточно проста и функциональна одновременно. Лишь недавно я открыл для себя jQuery File Uploader . «Он ничем не отличается от остальных» - скажите вы, но это не так. Его главное отличие - это простота и хорошая документация с примерами. В документации разобраны все callback"и, описаны все options. Внедрение в любую систему не занимает много времени.

Сегодня я покажу как можно очень просто организовать multipart загрузку файлов на сервер + drug&drop в CodeIgniter.

jQuery File Uploader + CodeIgniter Из коробки CodeIgniter предлагает нам использовать библиотеку $this->load->library("upload"); , которая позволяет контролировать передаваемые файлы, ограничивая загрузку по типу, размеру, ширине и высоте изображения. Использовать ее легко и удобно, но следует отметить небольшое ограничение налагаемое на INPUT данной библиотекой. Поле INPUT должно обязательно иметь параметр name=«userfile» . Соглашаемся с этим фактом и переходим в Controller к функции которая будет вызывать библиотеку Upload и, собственно, сохранять наши файлы на диск.

Пример реализации PHP функции:
public function upload(){ $config["upload_path"] = "/application/uploads/"; $config["allowed_types"] = "jpg|jpeg|png|gif|flv|mp4|wmv|doc|docx|xsl|xslx|ppt|pptx|zip|rar|tar"; $config["max_size"] = 2048; $config["max_width"] = 800; $config["max_height"] = 600; $config["encrypt_name"] = TRUE; $this->load->library("upload", $config); if ($this->upload->do_upload() == false) { $error = array("error" => $this->upload->display_errors()); echo json_encode($error); }else{ $data = $this->upload->data(); echo json_encode($data); } }

Внимание! Для того, что бы у Вас работали все allowed_types необходимо дописать недостающие MIME-Types в конфигурационный файл /application/config/mimes.php

У нас готова функция для сохранения файла на сервер. Переходим к клиентской части. Нам понадобится скачать с Github jQuery File Upload . Плагин предоставляет большие возможности, но все их использовать мы не будет, воспользуемся лишь загрузкой нескольких файлов, drug&drop и progressall.

Подключаем на страницу загрузки необходимые JS:
- jquery.fileupload.js - jquery.fileupload-video.js - jquery.fileupload-process.js - jquery.iframe-transport.js - upload.js //В комплекте не идет - напишем сами

И CSS файл:
- css/jquery.fileupload.css

Добавляем наш INPUT на страницу:
Добавить файл

Осталось совсем не много - написать upload.js, который будет прослушивать событие изменения поля INPUT и вызывать загрузку выбранного файла. «А где же обещанный Drug&Drop?» - спросите Вы. Drug&Drop уже работает благодаря jQuery File Upload. Вместо вызова стандартного диалога выбора файла вы можете перетащить сразу несколько файлов на страницу и они в порядке очереди загрузятся на сервер.

И на последок Upload.js
$(document).ready(function(){ $("#fileupload").fileupload({ dataType: "json", progressall: function (e, data) { var progress = parseInt(data.loaded / data.total * 100, 10); $(".progress .bar").css("width", progress + "%"); }, done: function (e, data) { if(data.result.error != undefined){ $("#error").html(data.result.error); // выводим на страницу сообщение об ошибке если оно есть $("#error").fadeIn("slow"); }else{ $("#error").hide(); //на случай если сообщение об ошибке уже отображалось $("#files").append(""); $("#success").fadeIn("slow"); } } } }); });

Data - это наш ответ от сервера, но он не является массивом с информацией о загруженном файле. Вся информация в формате JSON хранится в Data.Result. Кстати говоря console.log(data) поможет найти много интересных вещей, таких как: количество отправленных файлов, ошибки и многое другое.

Вот собственно и все, надеюсь на полезность материала.

В наше время веб-сайты становятся все более интерактивными. Это касается не только специализированных сервисов, но и обычных интернет магазинов, блогов и небольших сайтов. Основной особенностью является асинхронный 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 🙂).

Мы разберем одну из проблем, которую мне однажды пришлось решать, а именно — загрузка изображения на сайт с предварительным просмотром. Если вы меняли аватарку в вконтакте, вы понимаете о чем я пишу.

Нам понадобится 3 простых файла, это:

  • Страница с формой
  • php обработчик
  • файл js
index.html Ajax Upload Image upload Image file:

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

handler.php // Проверяем установлен ли массив файлов и массив с переданными данными if(isset($_FILES) && isset($_FILES["image"])) { //Переданный массив сохраняем в переменной $image = $_FILES["image"]; // Проверяем размер файла и если он превышает заданный размер // завершаем выполнение скрипта и выводим ошибку if ($image["size"] > 200000) { die("error"); } // Достаем формат изображения $imageFormat = explode(".", $image["name"]); $imageFormat = $imageFormat; // Генерируем новое имя для изображения. Можно сохранить и со старым // но это не рекомендуется делать $imageFullName = "./images/" . hash("crc32",time()) . "." . $imageFormat; // Сохраняем тип изображения в переменную $imageType = $image["type"]; // Сверяем доступные форматы изображений, если изображение соответствует, // копируем изображение в папку images if ($imageType == "image/jpeg" || $imageType == "image/png") { if (move_uploaded_file($image["tmp_name"],$imageFullName)) { echo "success"; } else { echo "error"; } } }

Это очень упрощенный обработчик. Имя картинки я сгенерировал использовав функцию hash . Хорошей практикой считается изменять имена файлов при загрузке их на сервер.

ajaxupload.js $(document).ready(function () { function readImage (input) { if (input.files && input.files) { var reader = new FileReader(); reader.onload = function (e) { $("#preview").attr("src", e.target.result); } reader.readAsDataURL(input.files); } } function printMessage(destination, msg) { $(destination).removeClass(); if (msg == "success") { $(destination).addClass("alert alert-success").text("Файл успешно загружен."); } if (msg == "error") { $(destination).addClass("alert alert-danger").text("Произошла ошибка при загрузке файла."); } } $("#image").change(function(){ readImage(this); }); $("#upload-image").on("submit",(function(e) { e.preventDefault(); var formData = new FormData(this); $.ajax({ type:"POST", // Тип запроса url: "handler.php", // Скрипт обработчика data: formData, // Данные которые мы передаем cache:false, // В запросах POST отключено по умолчанию, но перестрахуемся contentType: false, // Тип кодирования данных мы задали в форме, это отключим processData: false, // Отключаем, так как передаем файл success:function(data){ printMessage("#result", data); }, error:function(data){ console.log(data); } }); })); });

В этом скрипте происходит самое интересное. При помощи функции readImage() мы будем считывать файл с поля формы и передавать его в блок для предварительного просмотра. Создается объект FileReader . Он позволяет веб-приложению считывать содержимое файла на компьютере пользователя. Событие.onload сработает когда содержимое будет считано, при помощи этого события мы выведем изображение в блок предварительного просмотра.
И напоследок, метод.readAsDataURL() запускает процесс чтения файла, по завершению чтения будет выполнено событие.onload и картинка появится у вас на экране.

Функция printMessage создана для вывода информации об успешной или провалившейся попытке загрузки файла. Подробно не рассматриваем, ничего особенного не представляет.

Перехват формы и её обработка. При клике на кнопку «Отправить» событие будет перехвачено скриптом и при помощи функции.preventDefault() форма не отправит данные в index.html . .preventDefault() служит для отмены вызова каких-либо событий.

Объект FormData нужен нам для создания POST запроса к нашему скрипту, это намного проще чем вписывать каждый элемент формы в строку. Создали объект, заполнили данными, отдали в наш ajax .

Ну и собственно сам запрос AJAX . Поскольку мы используем библиотеку jQuery , составить и выполнить такой запрос не вызовет у вас никаких проблем.

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

Хорошего дня и успехов 🙂

Последнее обновление: 1.11.2015

В статье были рассмотрены общие моменты оптравки файлов на сервер в обычном запросе POST. Но если мы используем Ajax-запросы, то загрузка файлов будет иметь свои особенности.

Сначала определим метод в контроллере MVC:

Public JsonResult Upload() { foreach (string file in Request.Files) { var upload = Request.Files; if (upload != null) { // получаем имя файла string fileName = System.IO.Path.GetFileName(upload.FileName); // сохраняем файл в папку Files в проекте upload.SaveAs(Server.MapPath("~/Files/" + fileName)); } } return Json("файл загружен"); }

Здесь предполагается, что у нас в проекте определена папка Files для хранения загруженных файлов. Для получения файлов используется коллекция Request.Files

После сохранения файла пользователю отдается результат в виде строки.

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

@{ ViewBag.Title = "Home Page"; }
Загрузить @section scripts{ $("#submit").on("click", function (e) { e.preventDefault(); var files = document.getElementById("uploadFile").files; if (files.length > 0) { if (window.FormData !== undefined) { var data = new FormData(); for (var x = 0; x < files.length; x++) { data.append("file" + x, files[x]); } $.ajax({ type: "POST", url: "@Url.Action("Upload", "Home")", contentType: false, processData: false, data: data, success: function (result) { alert(result); }, error: function (xhr, status, p3) { alert(xhr.responseText); } }); } else { alert("Браузер не поддерживает загрузку файлов HTML5!"); } } }); }

Нам не нужна стандартная форма, все делается через ajax. Сначала получаем все выбранные файлы:

Var files = document.getElementById("uploadFile").files

Затем формируем объект FormData , в который добавляем все выбранные файлы:

Var data = new FormData(); for (var x = 0; x < files.length; x++) { data.append("file" + x, files[x]); }

И отсылаем их на сервер.

Асинхронная загрузка файлов в WebAPI

В Web API контроллер будет выглядеть следующим образом:

Public class ValuesController: ApiController { public async Task Post() { if (!Request.Content.IsMimeMultipartContent()) { return BadRequest(); } var provider = new MultipartMemoryStreamProvider(); // путь к папке на сервере string root = System.Web.HttpContext.Current.Server.MapPath("~/Files/"); await Request.Content.ReadAsMultipartAsync(provider); foreach (var file in provider.Contents) { var filename = file.Headers.ContentDisposition.FileName.Trim("\""); byte fileArray = await file.ReadAsByteArrayAsync(); using (System.IO.FileStream fs = new System.IO.FileStream(root + filename, System.IO.FileMode.Create)) { await fs.WriteAsync(fileArray, 0, fileArray.Length); } } return Ok("файлы загружены"); } }

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

Для асинхронного чтения с потока создается провайдер:

Var provider = new MultipartMemoryStreamProvider(); Request.Content.ReadAsMultipartAsync(provider);

После считывания потока свойство provider.Contents будет содержать все считанные значения, в том числе и файлы. И в цикле проходим по всем файлам и читаем их в массив байтов:

Byte fileArray = await file.ReadAsByteArrayAsync();

Затем с помощью объекта FileStream считанный массив сохраняется на диске в папке проекта.

Представление будет тем же, что и для MVC, за исключением url запроса:

$.ajax({ type: "POST", url: "api/values/post", contentType: false, processData: false, data: data, success: function (result) { alert(result); }, error: function (xhr, status, p3) { alert(status); } });

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

С помощью dmuploader мы создадим загрузчик, похожий по дизайну на тот, что реализован в wordpress. С Drag And Drop’ом и кликами! Преступим!

Структура проекта:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 #dropzone { border : 4px dashed #bbb ; border-radius : 5px ; color : #444 ; padding : 25px ; text-align : center ; } #dropzone .title { font-size : 20px ; } #dropzone input { -moz-border-bottom-colors: none ; -moz-border-left-colors: none ; -moz-border-right-colors: none ; -moz-border-top-colors: none ; border-color : transparent ; border-image: none ; cursor : pointer ; direction : ltr ; margin : 0 ; opacity: 0 ; position : absolute ; right : 0 ; top : 0 ; transform: translate(-300px , 0px ) scale(4 ) ; } #dropzone .browser span { background : #f7f7f7 ; border : 1px solid #ccc ; color : #555 ; cursor : pointer ; font-size : 16px ; height : 46px ; line-height : 44px ; padding : 0 36px ; } #dropzone .browser span:hover { border : 1px solid #999 ; }

Javascript:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 // index.php $(document) .ready (function () { $("#dropzone" ) .dmUploader ({ url: "upload.php" , dataType: "json" , maxFileSize: 256 * 1014 , allowedTypes: "image/*" , onBeforeUpload: function (id) { $) .show () ; } , onUploadSuccess: function (id, response) { $("div#output" ) .html ("" ) ; } , onUploadError: function (id, message) { $.jGrowl ("Файл: " + id + " не загрузился: " + message, { theme: "error" } ) ; } , onFileTypeError: function (file) { $.jGrowl (, { theme: "error" } ) ; } , onFileSizeError: function (file) { $.jGrowl ("Файл слишком большой!!" , { theme: "error" } ) ; } , onFallbackMode: function (message) { $.jGrowl ("Ваш браузер не поддерживается 8(" , { theme: "error" } ) ; } } ) ; } ) ;

Все! Клиенсткая часть готова. Немного подробнее:

  • DmUploader за нас подпишется на события drag для дом элемента #dropzone, а также на событие change для элемента input file.
  • При наступлении одного из событий, будет прочитан локальный файл с помощью file api.
  • У файла будет проверен размер и тип. В нашем случае, только картинки.
  • Удовлетворяющий всем проверкам файл будет загружен на сервер.
  • В процессе работы будут вызываться соответствующие коллбэки (callbacks). Например, onUploadSuccess вызовется после успешной загрузки файла. Вторым аргументом в функцию поступит ответ от сервера в формате json. Коллбэков у библиотеки больше, чем представлено в примере. С помощью них можно реализовать более сложные задачи.
  • Сервер

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 // upload.php require_once __DIR__ . "/protected/bootstrap.php" ; if (! IS_POST() || ! $_FILES ) { stopAndResponseMessage("error" , "Только POST, FILES" } $files = convertFileInformation($_FILES ) ; if (! isset ($files [ "file" ] ) ) { stopAndResponseMessage("error" , "Файл не загружался" ) ; } $file = $files [ "file" ] ; if ($file [ "error" ] !== UPLOAD_ERR_OK) { stopAndResponseMessage( "error" , uploadCodeToMessage($file [ "error" ] ) ) ; } $mimeType = guessMimeType($file [ "tmp_name" ] ) ; if (! $mimeType ) { stopAndResponseMessage("error" , "Тип файла не распознается!" ) ; } $validMimeType = [ "image/png" , "image/jpeg" ] ; if (! in_array ($mimeType , $validMimeType ) ) { stopAndResponseMessage( "error" , "Загружать можно только png и jpeg!" ) ; } $size = filesize ($file [ "tmp_name" ] ) ; if ($size > 256 * 1024 ) { stopAndResponseMessage("error" , "Файл слишком большой!!" ) ; } $uploadDir = __DIR__ . "/files" ; if (! is_writable ($uploadDir ) ) { stopAndResponseMessage( "error" , "Папка для файлов не доступна для записи." ) ; } $filename = time () . "-" . mt_rand (0000 , 9999 ) . "." . guessFileExtension($mimeType ) ; if (! move_uploaded_file ( $file [ "tmp_name" ] , $uploadDir . "/" . $filename ) ) { stopAndResponseMessage("error" , "Файл не был перемецен!" ) ; } sendResponse("upload" , [ "url" => "files/" . $filename ] ) ;

    Стоит заострить особое внимание на функции guessMimeType. Она с помощью расширения FileInfo определяет MIME тип файла. Как видно из кода, тип и размер файла, присланные от браузера не определяются при проверке. Их может подделать злоумышленник.

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 //protected/inc/func.php function guessMimeType($path , $magicFile = null ) { if (! is_file ($path ) ) { return null ; } if (! is_readable ($path ) ) { return null ; } if (! $finfo = new \finfo(FILEINFO_MIME_TYPE, $magicFile ) ) { return ; } return $finfo -> file ($path ) ; }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    Чтобы такой запрос состоялся, в 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 запрос):

    jQuery(document).ready(function($){ // ссылка на файл AJAX обработчик var ajaxurl = ""; var nonce = ""; var files; // переменная. будет содержать данные файлов // заполняем переменную данными, при изменении значения поля file $("input").on("change", function(){ files = this.files; }); // обработка и отправка 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("action", "ajax_fileload"); data.append("nonce", nonce); data.append("post_id", $("body").attr("class").match(/postid-(+)/)); var $reply = $(".ajax-reply"); // AJAX запрос $reply.text("Загружаю..."); $.ajax({ url: ajaxurl, type: "POST", data: data, cache: false, dataType: "json", // отключаем обработку передаваемых данных, пусть передаются как есть processData: false, // отключаем установку заголовка типа запроса. Так jQuery скажет серверу что это строковой запрос contentType: false, // функция успешного ответа сервера success: function(respond, status, jqXHR){ // ОК if(respond.success){ $.each(respond.data, function(key, val){ $reply.append(""); }); } // error else { $reply.text("ОШИБКА: " + respond.error); } }, // функция ошибки ответа сервера error: function(jqXHR, status, errorThrown){ $reply.text("ОШИБКА AJAX запроса: " + status); } }); }); })