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

Реклама

В этой заметке вы узнаете, как реализовать AJAX загрузку файлов на сервер с использованием jQuery. Это не так уж сложно!




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

Замечу заранее, что эта статья вряд ли поможет, если вы совсем плохо разбираетесь в jQuery и PHP, базовые знания обязательны. И, пожалуй, обязательно иметь хоть какой-то опыт в загрузке файлов (картинок) на сервер с обычной HTML формы, по крайней мере нужно представлять как это работает.

Ну, меньше слов, приступим!

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

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

1. Получение данных файла из поля file

Первое что нам нужно сделать — это получить данные input поля при добавлении в него файла(ов). Для этого прикрепим к событию change свою функцию, которая установит данные файла:

1
2
3
4
5
6
7
8
9
10
// Переменная куда будут располагаться данные файлов
var files;
// Вешаем функцию на событие
// Получим данные файлов и добавим их в переменную
$('input[type=file]').change(function(){
    files = this.files;
});

Этот код сохранит данные поля type=»file» в переменную files, с которой мы будем работать дальше.

2. Загружаем файлы по клику

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

Создадим функцию, повесим ее на событие click и отправим AJAX запрос с данными файлов. Этот запрос отличается от обычного AJAX запроса, и тут не подходит обычная отправка POST данных:

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
// Вешаем функцию ан событие 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(), добавляет в него данные файлов из массива files. Затем этот объект данных формы передается в AJAX запрос. 2 параметра нужно установить в false обязательно:

  • processData — потому что jQuery будет конвертировать массив files в строку, и сервер не сможет получить данные.
  • contentType — потому что дефолтные установки jQuery равны application/x-www-form-urlencoded, что не предусматривает отправку файлов. А еще, если установить этот параметр в multipart/form-data, похоже это ничего не даст.

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

Чтобы наглядно показать, как обрабатывать отправленный во втором пункте запрос, приведу простой php-скрипт, без всяких проверок.




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

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
<?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 сервер, зайдите в паку из архива, и попробуйте загрузить файл. Вы увидите, как все это работает, сможете «пошаманить» над кодом и разобраться подробнее в реальных условиях…

Статья взята с сайта: https://wpcafe.org