Більше результатів...

Загальні селектори
Тільки точні збіги
Шукати у заголовках
Шукати у контенті
Вибір типів постів
Фільтрувати за категоріями
FAQ
Hostenko
Натхнення
Відео уроки
Новини
Плагіни
теми
Уроки
Хакі

У цій нотатці ви дізнаєтесь, як реалізувати AJAX завантаження файлів на сервер за допомогою jQuery. Це не так уже й складно!

Не знаю точно, але щось мені підказує, що до появи jQuery завантаження файлів на сервер за AJAX технологією було чимось дуже незрозумілим, а отже, вкрай складним. Але сьогодні з появою jQuery веб-майстер, який навіть не володіє досвідом, може зробити це без особливих зусиль. Однак, так чи інакше, розібратися все ж таки доведеться. І зараз я спробую дуже коротко і зрозуміло пояснити вам, як це робиться, а щоб було простіше сприймати, урок містить тільки потрібне і розбитий на кроки.

Дивіться також:

Зауважу наперед, що ця стаття навряд чи допоможе, якщо ви зовсім погано знаєтеся на jQuery і PHP, базові знання обов'язкові. І, мабуть, обов'язково мати хоч якийсь досвід у завантаженні файлів (картинок) на сервер із звичайною HTML формою, принаймні потрібно уявляти як це працює.

Ну, менше слів, почнемо!

Для початку припустимо, що у нас є такий HTML код: поле та кнопка завантаження:

<input type="file" multiple="multiple" accept=".txt,image/*">
<a href="#" class="submit button">Загрузить файлы</a>
<div class="ajax-respond"></div>

1. Отримання даних файлу з поля файлу

Перше, що нам потрібно зробити — це отримати дані вхід поля при додаванні файлу(ів). Для цього прикріпимо до події зміна свою функцію, яка встановить дані файлу:

// Переменная куда будут располагаться данные файлов

var files;

// Вешаем функцию на событие
// Получим данные файлов и добавим их в переменную

$('input[type=file]').change(function(){
	files = this.files;
});

Цей код збереже дані поля type="file" в змінну файли, з якою ми будемо працювати далі.

2. Завантажуємо файли на кліку

Тепер нам потрібно повісити подію кліка на кнопку "Завантажити файлиТут і буде посилатися AJAX запит з даними файлів.

Створимо функцію, повісимо її на подію клацання і відправимо AJAX запит із даними файлів. Цей запит відрізняється від звичайного запиту AJAX, і тут не підходить звичайна відправка POST даних:

// Вешаем функцию ан событие click и отправляем AJAX запрос с данными файлов

$('.submit.button').click(function( event ){
	event.stopPropagation(); // Остановка происходящего
	event.preventDefault();  // Полная остановка происходящего

	// Создадим данные формы и добавим в них данные файлов из files

	var data = new FormData();
	$.each( files, function( key, value ){
		data.append( key, value );
	});

	// Отправляем запрос

	$.ajax({
		url: './submit.php?uploadfiles',
		type: 'POST',
		data: data,
		cache: false,
		dataType: 'json',
		processData: false, // Не обрабатываем файлы (Don't process the files)
		contentType: false, // Так jQuery скажет серверу что это строковой запрос
		success: function( respond, textStatus, jqXHR ){

			// Если все ОК

			if( typeof respond.error === 'undefined' ){
				// Файлы успешно загружены, делаем что нибудь здесь

				// выведем пути к загруженным файлам в блок '.ajax-respond'

				var files_path = respond.files;
				var html = '';
				$.each( files_path, function( key, val ){ html += val +'<br>'; } )
				$('.ajax-respond').html( html );
			}
			else{
				console.log('ОШИБКИ ОТВЕТА сервера: ' + respond.error );
			}
		},
		error: function( jqXHR, textStatus, errorThrown ){
			console.log('ОШИБКИ AJAX запроса: ' + textStatus );
		}
	});

});

Що виконує функція? Створює новий об'єкт new formData(), додає до нього дані файлів з масиву файли. Потім цей об'єкт даних форми передається в запит AJAX. 2 параметри потрібно встановити в false обов'язково:

  • processData - тому що jQuery конвертуватиме масив файли в рядок і сервер не зможе отримати дані.
  • contentType - тому що дефолтні установки jQuery рівні application / x-www-form-urlencoded, що не передбачає надсилання файлів. А ще, якщо встановити цей параметр у багаточастинні / форми-дані, схоже, це нічого не дасть.

3. Завантаження файлів на сервер

Щоб наочно показати, як обробляти надісланий у другому пункті запит, наведу простий php-скрипт без жодних перевірок.

Створимо файл submit.php і додамо в нього цей код (передбачається, що submit.php лежить у тій же папці, де і файл, з якого відправляється AJAX запит):

<?php

// Здесь нужно сделать все проверки передаваемых файлов и вывести ошибки если нужно

// Переменная ответа

$data = array();

if( isset( $_GET['uploadfiles'] ) ){
	$error = false;
	$files = array();

	$uploaddir = './uploads/'; // . - текущая папка где находится submit.php

	// Создадим папку если её нет

	if( ! is_dir( $uploaddir ) ) mkdir( $uploaddir, 0777 );

	// переместим файлы из временной директории в указанную
	foreach( $_FILES as $file ){
		if( move_uploaded_file( $file['tmp_name'], $uploaddir . basename($file['name']) ) ){
			$files[] = realpath( $uploaddir . $file['name'] );
		}
		else{
			$error = true;
		}
	}

	$data = $error ? array('error' => 'Ошибка загрузки файлов.') : array('files' => $files );

	echo json_encode( $data );
}

Не використовуйте цей код! Пишіть свій!

Ось і все.

Висновок

Ця стаття лише навчає технології завантаження файлів за допомогою AJAX. Насправді, вам потрібно перевірити формати файлів, їх розмір і повідомити користувачів, що відбулося завантаження файлу.

Щоб не збирати весь вищеописаний код вручну, скачайте цей архів: ajax-file-upload.zip. Завантажте його вміст на ваш php сервер, зайдіть в пакет з архіву, і спробуйте завантажити файл. Ви побачите, як все це працює, зможете "пошаманити" над кодом і розібратися докладніше в реальних умовах.

Також, рекомендую до прочитання статтю про базові знання для створення AJAX запитів у WordPress:

Ajax у WordPress

Знання з цієї статті вам знадобляться при створенні AJAX завантаження файлів під WordPress.

Автор: Тимур Камаєв
редактор wpcafe
Вивчає сайтобудування з 2008 року. Практикуючий вебмайстер, який спеціалізується на створенні сайтів на WordPress. Задати питання Олексію можна на https://profiles.wordpress.org/wpthemeus/

Коментарі до запису: 43

Максим:

Все це, звичайно, цікаво, але на HTML5 + останній jQuery не працює.
Видає ПОМИЛКИ AJAX запиту: error :) до сервера справа не доходить.

Никита:

Зміни тип json на html і все. Правда, не у всіх браузерах буде працювати.

Слава:

в ajax не сильний, як мені другий параметр, разом із data передати в submit.php

спробував конструкцію
data : {'data':data, 'id':id}
не спрацьовує

Fdnj:

Вставляєте так само:
data.append (key, value);
у submit.php:
$var = $_POST[key]; // отримуємо value

Віталій:

У мене не працює
data.append(eventId, eventId);
$eventId=$_POST['eventId'];

Євген:

data.append('eventId', eventId);

ya:

навіщо викладати неробочий код?
добре б стаття була стара, а тут спочатку викладено марний код ...

каша:

все працює, з невеликими переробками у себе використав

Ігор:

Дякую! Все працює. Відправляв файл аяксом вперше, Ваша стаття чудово допомогла розібратися. Правда не вдалося відправити у форматі json, довелося використовувати xml. І так, було б добре винести в саму статтю про data.append(key, value); т.к. голий файл рідко треба надсилати. Для each треба додати if, якщо файл є необов'язковим і не вибрано. І якщо сайт називається «про WordPress за чашкою кави», то правильно було б навести приклад саме для WP, адреса wp-admin/admin-ajax.php, та обробка відповіді від WP. Це рекомендації, а так ще раз дякую за статтю.

Антон:

Панове, в наш час за такий приклад викликали на дуель.
Код не працює.

Svmp:

І ти програв би на дуелі, код працює

Артем:

Чудова стаття. Вперше показали, мабуть, найпростіший спосіб завантаження файлів без перезавантаження сторінки. Раніше для цього використовував невидимий тег iframe , вказував його як target для форми, а потім вже з нього повертався в батьківську (поточну) форму. Приємно дізнатися, що це можна робити більш простим способом через AJAX

TEster:

пиздюк!, я на твій неробочий код пів дня витратив, морду б тобі набити

Svmp:

А ти не висловлюйся а учи JS і PHP

Анонімус:

А те, що на сервері приймає GET, відправляється POST'ом тебе не збентежило?

Євген:

А чому має збентежити, що змінна відправлена ​​GET параметром приходить разом із запитом POST? Розберіться спершу. Ніхто не забороняє використовувати GET разом з POST і в даному випадку файли передаються через POST, а змінна uploadfiles у рядку './submit.php?uploadfiles' GET параметром, якщо ви звичайно розумієте, що змінна в адресі після знака запитання це завжди GET параметр.

Svmp:

Напевно бібліотеку jQuery забув підключити

srgTS:

Фільтруй мову! код робочий і розміщений тут для ПРИКЛАДА а якщо ти не хочеш розбиратися сам, то вали на freelance.ru і там адекватні люди зроблять все за тебе

ЖЖЖ:

Складно, незрозуміло, криво. Є бібліотека autoload.js там все простіше...

ЖЖЖ:

upd. навіть не можна тут свою посаду відредагувати… думав про інше… ajaxupload.3.5.js

Діма:

Дякую, легко та просто.

Алекс:

Маючи мозок, я їм подумав), перед тим як витрачати час. А код випадково не для html5? Якщо так, то весь сенс губиться. Атрибути дивні в HTML. Без них працюватиме?

Бобов:

Майже все добре працює. Два питання. 1. До директорії на сервері імена файлів переносяться нормально тільки якщо вони в латиниці. У кирилиці пишеться абракадабра. До того ж користувачу повертаються імена нормально. Як цього позбутися? 2. Завантажується лише один останній вибраний файл. Як завантажити декілька?

Trionika:

Код із прикладу не працює.

Георгій:

Смішно, ajax відправляє дані POST запитом, а на сервері чомусь GET

Євген:

Придивіться:

url: './submit.php?uploadfiles',
type: 'POST',
дані: дані,

Тут data передається методом POST і доступна через змінну $_POST, але оскільки це файли, то $FILES, а uploadfiles вказано GET параметром. Разом запит йде на ./submit.php зі змінною $_GET['uploadfiles'] і змінними в $_POST / $_FILES передані методом $_POST. Ніхто не забороняє одночасно передавати GET і POST дані.

Микола:

Дякую! Все працює, у кого не виходить просто упускають щось, у моєму випадку мені був потрібен лише один файл і я додав його так:
var data = новий FormData();
data.append("name", $("input[type=file]")[0].files[0]);

і щоб не було помилок обов'язково використовувати:
processData: false,
contentType: false,

Олександр:

Підкажіть, як вже завантажені файли надсилати на пошту?

Сергій:

Дякую. Все працює, але довелося видалити ці два рядки:
event.stopPropagation();
event.preventDefault();
інакше код далі цих рядків не виконується.
подія click зчитується через метод on та діє на це посилання
Відповісти
ну і дані в files зчитую через метод on теж
$('body').on('change', '#otvet-file', function() {
files = this.files;
});
інакше в файлі нічого не зчитує.
У моєму випадку поле input та посилання підвантажувалися в модальне вікно за допомогою ajax.
Для інших випадків не перевірялося, може код і працює без видалення тих двох рядків.

Rusic:

Клас ))

Rusic:

Можна було забрати замість двох рядків, тільки верхню, друга зупиняє стандартну обробку форми

Rusic:

Гарна стаття, але я поправив трохи, думаю народу буде теж цікавіше не шляхи файлів бачити а картинки. Та й у формі accept розширити accept="image/jpeg,image/png,image/gif"
підправити:
submit.php
$files[] = realpath( $uploaddir . $file['name'] );
на
$files[] = $uploaddir . $file['name'];

замість:
$.each( files_path, function( key, val ){ html += val +»; } )
написати:
$.each( files_path, function( key, val ){ html += »; } )

само собою підправити трохи css
наприклад так
.admin .ajaxRespond {
display: -webkit-flex;
дисплей: flex;
}
.admin .ajaxRespond-imgPreview {
width: 200px;
}

А так, звичайно, все супер, я ще накинув створення прев'ю і ресайз коротше, зіштовхнув справу з мертвої точки. Все хотів та ніяк. )

kotjarko:

Якщо «надсилати» без файлів — помилка :) Лікується ось таким рядком

event.preventDefault(); // Повна зупинка того, що відбувається
if (typeof files == 'undefined') return;

Дякую за примірник.

Кама:

Доброго дня!

Я на правах автора статті, прошу прибрати nofollow із посилань на мій сайт (wp-kama.ru), як це було спочатку.

Також прошу, наприкінці статті вказати моє авторство, а то там чомусь «джерело» вказано, коли на сайті у мене немає статті, присвяченої цій темі.

Спасибо!

П.С. не знайшов контактів, тож пиши суду.

Кама:

Мій попередній комент проігноровано і видалено чи що?

WPcafe.org:

Все готово!

Кама:

Спасибо!

Павло:

Шановні!
Оберніть код у форму, замість click(function використовуйте submit(function тобто подія на форму, а не на кнопку). форми, у тому числі й прикріплений файл.
$('#form').submit(function(){
var form_data = новий FormData($(this).get(0));
$ .ajax ({
url: './submit.php?uploadfiles',
type: 'POST',
data: form_data,
кеш: false,
dataType: 'json',
processData: false, // Не обробляємо файли (Don't process the files)
contentType: false,
success: function(){}
}
на виході отримаєте і POST та FILE

Олексій:

Дякую за код, не вперше його використовую. Але востаннє чомусь data.append( key, value ); ніяк не хоче працювати. var data = новий FormData();
$.each( files, function( key, value ){
console.log(key+';'+value);
data.append (key, value);
});
console.log (дані);
У консоль виводить усі файли - console.log(key+';'+value); але data — порожній… помилки js не видає….

Олексій:

Загалом вийшло так, що змінив dataType: на HTML, вніс невеликі редагування і запрацювало!

Мхер:

Доброго вечора панове. Код у мене чомусь не заробив. а саме

var data = новий FormData();
$.each( files, function( key, value ){
data.append(key, value);
при console.log(data) порожній об'єкт

Додати коментар або відгук