Кажется, я не могу завершить забавные вещи, которые вы можете сделать с помощью новых веб-технологий. Сегодня я собираюсь показать вам, как сделать что-то, что до последнего времени было практически беспрецедентным: загрузка файлов через AJAX.
О, конечно, были взломы; но если вы похожи на меня и чувствуете себя грязным каждый раз, когда вы iframe
, вам это очень понравится. Присоединяйся ко мне после прыжка!
Ищете быстрое решение?
Если вы ищете быстрое решение, на Envato Market есть большая коллекция скриптов и приложений для загрузки файлов .
Это средство загрузки файлов HTML5 особенно изящно — вы можете легко добавлять файлы, перетаскивая их или щелкая. Все файлы будут загружены через AJAX или могут быть добавлены в форму, и файлы могут быть переименованы перед загрузкой. Отличное, быстрое решение, если это то, что вы ищете!
Почему бы нам не покончить с плохими новостями?
Это не работает в каждом браузере. Однако, с некоторым прогрессивным улучшением (или каким-либо другим текущим модным словом), у нас будет страница загрузки, которая будет работать обратно в IE6 (хотя и без битов AJAXy).
Наша загрузка 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
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
<!DOCTYPE html>
<html lang=»en»>
<head>
<meta charset=»UTF-8″ />
<title>HTML5 File API</title>
<link rel=»stylesheet» href=»style.css» />
</head>
<body>
<div id=»main»>
<h1>Upload Your Images</h1>
<form method=»post» enctype=»multipart/form-data» action=»upload.php»>
<input type=»file» name=»images» id=»images» multiple />
<button type=»submit» id=»btn»>Upload Files!</button>
</form>
<div id=»response»></div>
<ul id=»image-list»>
</ul>
</div>
<script src=»https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js»></script>
<script src=»upload.js»></script>
</body>
</html>
|
Довольно простой, а? У нас есть форма, которая публикует upload.php
, который мы рассмотрим через секунду, и один элемент ввода типа file
. Обратите внимание, что он имеет логический атрибут multiple
, который позволяет пользователю выбирать несколько файлов одновременно.
Это действительно все, что можно увидеть здесь. Давайте двигаться дальше.
CSS
01
02
03
04
05
06
07
08
09
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
|
body {
font: 14px/1.5 helvetica-neue, helvetica, arial, san-serif;
padding:10px;
}
h1 {
margin-top:0;
}
#main {
width: 300px;
margin:auto;
background: #ececec;
padding: 20px;
border: 1px solid #ccc;
}
#image-list {
list-style:none;
margin:0;
padding:0;
}
#image-list li {
background: #fff;
border: 1px solid #ccc;
text-align:center;
padding:20px;
margin-bottom:19px;
}
#image-list li img {
width: 258px;
vertical-align: middle;
border:1px solid #474747;
}
|
Абсолютно нет шокеров здесь.
Шаг 2: PHP
Нам нужно уметь обрабатывать загрузку файлов и на серверной части, поэтому давайте рассмотрим это позже.
upload.php
01
02
03
04
05
06
07
08
09
10
|
<?php
foreach ($_FILES[«images»][«error»] as $key => $error) {
if ($error == UPLOAD_ERR_OK) {
$name = $_FILES[«images»][«name»][$key];
move_uploaded_file( $_FILES[«images»][«tmp_name»][$key], «uploads/» . $_FILES[‘images’][‘name’][$key]);
}
}
echo «<h2>Successfully Uploaded Images</h2>»;
|
Имейте в виду, что это были первые строки PHP, которые я написал за год ( я парень из Ruby ). Вы, вероятно, должны сделать немного больше для безопасности; однако мы просто следим за тем, чтобы ошибок при загрузке не было. Если это так, мы используем встроенный move_uploaded_file
чтобы переместить его в папку uploads
. Не забудьте убедиться, что папка доступна для записи.
Итак, сейчас у нас должна быть рабочая форма загрузки. Вы выбираете изображение (несколько, если вы хотите, и ваш браузер позволяет вам), нажмите « Загрузить файлы! », И вы получите сообщение« Успешно загруженные изображения. »
Вот как выглядит наш мини-проект:
Но давай, это 2011 год: мы хотим большего. Вы заметите, что мы связали jQuery и файл upload.js
. Давайте сейчас раскроем это.
Шаг 3: JavaScript
Давайте не будем тратить время зря!
(function () { var input = document.getElementById ("images"), formdata = false; if (window.FormData) { formdata = new FormData (); document.getElementById ("btn"). style.display = "none"; } } ();
Вот с чего мы начнем. Мы создаем две переменные: input
— наш элемент ввода файла; formdata
будет использоваться для отправки изображений на сервер, если браузер поддерживает это. Мы инициализируем его как false
и затем проверяем, поддерживает ли браузер FormData
; Если это так, мы создаем новый объект FormData
. Кроме того, если мы можем отправить изображения с помощью AJAX, нам не нужна кнопка «Загрузить изображения!», Поэтому мы можем ее скрыть. Почему нам это не нужно? Что ж, мы собираемся автоматически загружать изображения сразу после того, как пользователь их выберет.
Остальная часть JavaScript войдет в вашу анонимную функцию самовызвания. Затем мы создадим небольшую вспомогательную функцию, которая будет показывать изображения, как только они появятся в браузере:
функция showUploadedItem (source) { var list = document.getElementById ("список изображений"), li = document.createElement ("li"), img = document.createElement ("img"); img.src = источник; li.appendChild (IMG); list.appendChild (Li); }
Функция принимает один параметр: источник изображения (скоро мы увидим, как мы это получим). Затем мы просто находим список в нашей разметке и создаем элемент списка и изображение. Мы устанавливаем источник изображения в качестве источника, который мы получили, помещаем изображение в элемент списка и помещаем элемент списка в список. Вуаля!
Затем мы должны взять изображения, отобразить их и загрузить. Как мы уже говорили, мы сделаем это, когда событие onchange
будет onchange
элемента input.
if (input.addEventListener) { input.addEventListener ("change", function (evt) { var i = 0, len = this.files.length, img, reader, file; document.getElementById ("response"). innerHTML = "Загрузка..." for (; i <len; i ++) { file = this.files [i]; if (!! file.type.match (/ image. * /)) { } } }, ложный); }
Нам не нужно беспокоиться о патентованной модели событий IE, потому что IE9 + поддерживает стандартную функцию addEventListener.
Это еще не все, но давайте начнем с этого. Во-первых, нам не нужно беспокоиться о патентованной модели событий IE, потому что IE9 + поддерживает стандартную функцию addEventListener
(а IE9 и ниже не поддерживают наши новые функции).
Итак, что мы хотим сделать, когда пользователь выбрал файлы? Сначала мы создадим несколько переменных. Единственный важный сейчас — это len = this.files.length
. Файлы, которые выбрал пользователь, будут доступны из объекта this.files
. Сейчас нас интересует только свойство length
, поэтому мы можем зацикливаться на файлах…
… это именно то, что мы делаем дальше. Внутри нашего цикла мы устанавливаем текущий файл в file
для удобства доступа. Следующее, что мы делаем, это подтверждаем, что файл является изображением. Мы можем сделать это, сравнивая свойство type
с регулярным выражением. Мы ищем тип, который начинается с «изображения» и сопровождается чем угодно. (Двойной удар впереди преобразует результат в логическое значение.)
Итак, что нам делать, если у нас на руках изображение?
if (window.FileReader) { читатель = новый FileReader (); reader.onloadend = function (e) { showUploadedItem (e.target.result); }; reader.readAsDataURL (файл); } if (formdata) { formdata.append ("images []", файл); }
Мы проверяем, поддерживает ли браузер создание объектов FileReader
. Если это произойдет, мы создадим один.
Вот как мы используем объект FileReader
: мы собираемся передать наш file
объект методу reader.readAsDataURL
. Это создает URL-адрес данных для загруженного изображения. Однако это не работает так, как вы могли бы ожидать. URL-адрес данных не передается обратно из функции. Вместо этого URL-адрес данных будет частью объекта события.
Имея это в виду, нам нужно зарегистрировать функцию reader.onloadend
события 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
, вот последняя часть нашей головоломки:
if (formdata) { $ .Ajax ({ URL: "upload.php", тип: "POST", данные: формданные, processData: false, contentType: false, success: function (res) { document.getElementById ("response"). innerHTML = res; } }); }
Опять же, мы должны убедиться, что у нас FormData
поддержка FormData
; если мы этого не сделаем, кнопка «Загрузить файлы!» будет видна, и именно так пользователь будет загружать фотографии. Однако, если у нас FormData
поддержка FormData
, мы позаботимся о загрузке через AJAX. Мы используем jQuery для обработки всех странностей AJAX в разных браузерах.
Вы, вероятно, знакомы с методом jQuery $.ajax
: вы передаете ему объект параметров. Свойства url
, type
и success
должны быть очевидны. Свойство data
является нашим объектом formdata
. Обратите внимание на эти свойства processData
и contentType
. Согласно документации jQuery, processData
по умолчанию имеет значение true
и будет обрабатывать и преобразовывать данные в строку запроса. Мы не хотим этого делать, поэтому мы устанавливаем это в false
. Мы также устанавливаем для contentType
значение false
чтобы гарантировать, что данные поступают на сервер так, как мы ожидаем.
Вот и все. Теперь, когда пользователь загружает страницу, он видит это:
И после того, как они выберут изображения, они увидят это:
И изображения были загружены:
Это упаковка!
Загрузка файлов через AJAX — это здорово, и это здорово, что эти новые технологии поддерживают это без необходимости длительных хаков. Если у вас есть какие-либо вопросы о том, что мы сделали здесь, нажмите на эти комментарии! Большое спасибо за чтение!
И если вам все еще нужна помощь в решении этой или любой другой проблемы с кодированием, обратитесь за поддержкой в Envato Studio .
Изучите JavaScript: полное руководство
Мы создали полное руководство, которое поможет вам изучить JavaScript , независимо от того, начинаете ли вы как веб-разработчик или хотите изучать более сложные темы.