Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. Web Development
Code

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

by
Difficulty:IntermediateLength:LongLanguages:

Russian (Pусский) translation by Marat Amerov (you can also view the original English article)

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

О, конечно, были хаки; но если вы похожи на меня и чувствуете себя грязными каждый раз, когда вы вводите iframe, вам это очень понравится. Присоединяйтесь ко мне!

Ищете быстрое решение?

Если вы ищете быстрое решение, на Envato Market имеется большая коллекция скриптов и приложений для загрузки файлов.

Этот HTML5 загрузчик файлов  особенно примечателен - вы можете легко добавлять файлы, перетаскивая их или кликая. Все файлы будут загружены через AJAX или могут быть добавлены в форму, и файлы могут быть переименованы перед загрузкой. Отличное, быстрое решение, если это то, что вы ищете!


У нас имеются плохие новости?

Это не работает во всех браузерах. Однако с некоторым прогрессивным улучшением (или каким бы то ни было текущим модным словом) у нас будет страница загрузки, которая будет работать даже в IE6 (хотя и без черт AJAX).

Наша  AJAX-загрузка будет работать до тех пор, пока доступен FormData; в противном случае пользователь получит обычную загрузку.

В нашем проекте есть три основных компонента.

  • multiple атрибуты элемента input файла.
  • Объект FileReader из нового API файлов.
  • Объект FormData из XMLHttpRequest2.

Мы используем атрибут multiple, чтобы позволить пользователю выбирать несколько файлов для загрузки (многократная загрузка файлов будет работать нормально, даже если FormData недоступен). Как вы увидите, FileReader позволяет нам показывать миниатюры загружаемых файлов (мы будем ожидать изображения).

Ни одна из наших трех функций не работает в IE9, поэтому все пользователи IE получат нормальную загрузку (хотя я понимаю, что поддержка `FileReader` доступна в IE10 Dev Preview 2). FileReader не работает в последней версии Safari (5.1), поэтому они не получат миниатюры, но они получат загрузку AJAX и подтверждение. Наконец, Opera 10.50 поддерживает FileReader, но не поддерживает FormData, поэтому он получит миниатюры, но обычную загрузку.

Чтобы продолжить путь, давайте приступим к кодированию!


Шаг 1: Разметка и стилизация

Начнем с некоторой базовой разметки и стилизации. Конечно, это не основная часть этого урока, я не буду относиться к вам как к новичку.

HTML-код

Довольно просто, не так ли? У нас есть форма, в которая отправляется post'ом на upload.php, который мы рассмотрим через секунду, и один элемент ввода, типа file. Обратите внимание, что он имеет boolean-атрибут multiple, который позволяет пользователю одновременно выбирать несколько файлов.

Это действительно все, что нужно было здесь увидеть. Давайте двигаться дальше.

CSS

Здесь нет абсолютно никаких особенностей.


Шаг 2: PHP

Мы также должны иметь возможность обрабатывать загрузки файлов на стороне сервера, поэтому давайте рассмотрим это далее.

upload.php

Имейте в виду, что это были первые строки на PHP, которые я написал с легкостью первый год (я парень из Ruby). Вероятно, вам стоит немного позаботиться о безопасности; однако мы просто следим за тем, чтобы не было ошибок при загрузке. Мы используем встроенную функцию move_uploaded_file, чтобы переместить файл в папку uploads. Не забудьте убедиться, что папка доступна для записи.

Итак, прямо сейчас у нас должна быть рабочая форма загрузки. Вы выбираете изображение (несколько, если хотите, и ваш браузер это позволяет), нажмите кнопку “Upload Files!”, и вы получите сообщение “Successfully Uploaded Images.”

Вот как выглядит наш мини-проект:

The styled form

Но, сейчас 2011 год: мы хотим большего. Вы заметите, что мы связали jQuery и файл upload.js. Давайте рассмотрим это подробней.


Шаг 3: JavaScript

Давайте не будем терять время: здесь начнем!

Вот с чего мы начинаем. Мы создаем две переменные: input - это наш элемент ввода файла; formdata будет использоваться для отправки изображений на сервер, если браузер поддерживает это. Мы инициализируем его значением false, а затем проверяем, поддерживает ли браузер FormData; Если это так, мы создаем новый объект FormData. Кроме того, если мы можем отправить изображения с помощью AJAX, нам не нужна кнопка “Upload Images!”, Поэтому мы можем скрыть ее. Почему нам это не нужно? Ну, мы собираемся автоматически загружать изображения сразу после того, как пользователь их выбирает.

Остальная часть JavaScript войдет в вашу анонимную функцию. Затем мы создадим небольшую вспомогательную функцию, которая будет отображать изображения в браузере:

Функция принимает один параметр: источник изображения (мы увидим, как его получать). Затем мы просто находим список в нашей разметке и создаем элемент списка и изображение. Мы установили источник изображения в полученный нами источник, поместили изображение в элемент списка и поместили элемент списка в список. Вуаля!

Затем мы должны фактически отображать изображения, отображать их и загружать. Как мы уже говорили, мы это сделаем, когда событие onchange будет запущено на входном элементе.

Нам не нужно беспокоиться о проприетарной модели событий IE, потому что IE9 + поддерживает стандартную функцию addEventListener.

Там доступно больше возможностей, но давайте начнем с этого. Во-первых, нам не нужно беспокоиться о проприетарной модели событий IE, потому что IE9 + поддерживает стандартную функцию addEventListener (а IE9 и ниже не поддерживают новые функции).

Итак, что мы хотим делать, когда пользователь выбрал файлы? Во-первых, мы создаем несколько переменных. Единственный важный момент сейчас - это len = this.files.length. Файлы, которые пользователь выбрал, будут доступны из объекта this.files. Прямо сейчас, нас беспокоит только свойство length, поэтому мы можем перебирать файлы ...

... это именно то, что мы делаем дальше. Внутри нашего цикла мы устанавливаем текущий файл в file для удобства доступа. Следующее, что мы делаем, это подтверждение того, что файл является изображением. Мы можем сделать это, сравнивая свойство type с регулярным выражением. Мы ищем тип, начинающийся с "image", за которым следует что-либо. (Двойной знак восклицания впереди просто преобразует результат в булев тип.)

Итак, что нам делать, если у нас есть изображение на руках?

Мы проверяем, поддерживает ли браузер создание объектов FileReader. Если это произойдет, мы его создадим.

Вот как мы используем объект FileReader: мы собираемся передать наш объект file методу reader.readAsDataURL. Это создает URL-адрес для загруженного изображения. Однако это не работает так, как вы ожидали. URL-адрес данных не возвращается из функции. Вместо этого URL-адрес данных будет частью объекта события.

Имея это в виду, нам нужно зарегистрировать функцию на событие reader.onloadend. Эта функция принимает объект события, с помощью которого мы получаем URL-адрес данных: он находится на e.target.result (да, e.target является объектом reader, но у меня были проблемы при использовании reader вместо e.target внутри этой функции) , Мы просто передадим этот URL-адрес нашей функции showUploadedItem (которую мы написали выше).

Затем мы проверяем объект formdata. Помните, что если браузер поддерживает FormData, formdata будет объектом FormData; в противном случае оно будет false. Итак, если у нас есть объект FormData, мы будем вызывать метод append. Цель объекта FormData - хранить значения, которые вы отправляете через форму; поэтому метод append просто берет ключ и значение. В нашем случае наш ключ - images[]; добавив квадратные скобки к концу, мы проверяем каждый раз, что append добавляет другое значение, мы фактически добавляем его к этому массиву, а не переписываем свойство image.

Мы почти закончили. В нашем цикле for мы отобразили каждое изображение для пользователя и добавили его в объект formdata. Теперь нам просто нужно загрузить изображения. Снаружи цикла for, вот последний фрагмент нашего пазла:

Опять же, мы должны убедиться, что у нас есть поддержка FormData; если мы этого не сделаем, кнопка “Upload Files!” будет видна, и пользователь загрузит фотографии. Однако, если у нас есть поддержка FormData, мы позаботимся о загрузке через AJAX. Мы используем jQuery для обработки всех особенностей AJAX во всех браузерах.

Вероятно, вы знакомы с методом $.ajax jQuery: вы передаете ему объект options. Свойства url, type и success обязательны. Свойством data является наш объект formdata. Обратите внимание на свойства processData и contentType. Согласно документации jQuery, processData по умолчанию является true и будет обрабатывать и преобразовывать данные в строку запроса. Мы не хотим этого делать, поэтому мы устанавливаем значение false. Мы также устанавливаем contentType в false, чтобы убедиться, что данные попадают на сервер, как мы и ожидаем.

Вот и все. Теперь, когда пользователь загружает страницу, они видят это:

Tutorial Image

И после того, как они выберут изображения, они увидят это:

Tutorial Image

Так же были загружены изображения:

Tutorial Image

Заключение

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

И если вам по-прежнему нужна помощь в этой или любой другой проблеме с кодингом, вы можете найти решение в Envato Studio.

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.