Создание превью изображений с помощью HTML5 File API и jQuery и отправка их на сервер с использованием AJAX
Содержание:
- Множественный выбор файлов, создание превью на стороне клиента и отправка данных ajax’ом на сервер
- Добавляем прогресс-бар
- Готовые решения для загрузки изображений на сервер
1. Множественный выбор файлов, создание превью на стороне клиента и отправка данных ajax-ом на сервер
В примере представлен код для множественного выбора файлов, их валидации (проверка на формат и размер) и загрузки их с помощью ajax на сервер.
Подключаем jQuery
1 2 3 4 5 |
<head> ... <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> ... </head> |
Форма для выбора, отображения и отправки файлов:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<form action="uploadImages.php" method="post" enctype="multipart/form-data" id="uploadImages"> <input type="file" id="addImages" multiple=""> <input type="hidden" name="azaza" value="zazaza"> <ul id="uploadImagesList"> <li class="item template"> <span class="img-wrap"> <img src="image.jpg" alt=""> </span> <span class="delete-link" title="Удалить">Удалить</span> </li> </ul> <div class="clear"></div> <div> <input type="submit" value="Отправить"> </div> </form> |
JS код создания превью и отправки формы:
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 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
<script> jQuery(document).ready(function ($) { var maxFileSize = 2 * 1024 * 1024; // (байт) Максимальный размер файла (2мб) var queue = {}; var form = $('form#uploadImages'); var imagesList = $('#uploadImagesList'); var itemPreviewTemplate = imagesList.find('.item.template').clone(); itemPreviewTemplate.removeClass('template'); imagesList.find('.item.template').remove(); $('#addImages').on('change', function () { var files = this.files; for (var i = 0; i < files.length; i++) { var file = files[i]; if ( !file.type.match(/image\/(jpeg|jpg|png|gif)/) ) { alert( 'Фотография должна быть в формате jpg, png или gif' ); continue; } if ( file.size > maxFileSize ) { alert( 'Размер фотографии не должен превышать 2 Мб' ); continue; } preview(files[i]); } this.value = ''; }); // Создание превью function preview(file) { var reader = new FileReader(); reader.addEventListener('load', function(event) { var img = document.createElement('img'); var itemPreview = itemPreviewTemplate.clone(); itemPreview.find('.img-wrap img').attr('src', event.target.result); itemPreview.data('id', file.name); imagesList.append(itemPreview); queue[file.name] = file; }); reader.readAsDataURL(file); } // Удаление фотографий imagesList.on('click', '.delete-link', function () { var item = $(this).closest('.item'), id = item.data('id'); delete queue[id]; item.remove(); }); // Отправка формы form.on('submit', function(event) { var formData = new FormData(this); for (var id in queue) { formData.append('images[]', queue[id]); } $.ajax({ url: $(this).attr('action'), type: 'POST', data: formData, async: true, success: function (res) { alert(res) }, cache: false, contentType: false, processData: false }); return false; }); }); </script> |
Демо (выберите изображения, для которых нужно создать превью):
Данные из примера на сервер попадут в следующем виде:
Стили, используемые в примере:
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 |
<style> #uploadImagesList { list-style: none; padding: 0; } #uploadImagesList .item { float: left; margin-right: 20px; margin-bottom: 20px; } #uploadImagesList .item .img-wrap { width: inherit; display: block; height: 150px; } #uploadImagesList .item .img-wrap img{ width: auto; height: inherit; } #uploadImagesList .item .delete-link { cursor: pointer; display: block; } .clear { clear: both; } </style> |
2. Добавляем прогресс-бар.
Добавляем в код формы html-код прогресс-бара:
1 2 3 4 |
<div id="progress-bar"> <div class="progress-bg"></div> <div class="progress-val">0%</div> </div> |
Добавляем css-код:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
#progress-bar { margin-top: 20px; width: 300px; height: 20px; background: #999999; position: relative; } #progress-bar .progress-bg { position: absolute; width: 0; height: inherit; background: green; } #progress-bar .progress-val { position: absolute; text-align: center; width: inherit; height: inherit; } |
JS-код:
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 |
// Отправка формы form.on('submit', function(event) { var formData = new FormData(this); for (var id in queue) { formData.append('images[]', queue[id]); } $.ajax({ url: $(this).attr('action'), type: 'POST', data: formData, async: true, xhr: function() { var xhr = new window.XMLHttpRequest(); var progressBar = $('#progress-bar'), progressBg = progressBar.find('.progress-bg'), progressVal = progressBar.find('.progress-val'); // Upload progress xhr.upload.addEventListener("progress", function(evt){ if (evt.lengthComputable) { var percentComplete = evt.loaded / evt.total; percentComplete = (percentComplete * 100).toFixed(); progressBg.css('width', percentComplete + '%'); progressVal.text(percentComplete + '%'); // console.log(percentComplete); } }, false); return xhr; }, success: function (res) { alert(res) }, cache: false, contentType: false, processData: false }); return false; }); |
Результат:
Подробнее про индикацию прогресса в JS.
3. Готовые решения для загрузки изображений на сервер
DropzoneJS — создаёт область для перетаскивания файлов и загружает их на сервер
jQuery.fileapi — библиотека для работы с FileAPI от mail.ru