Пошаговая инструкция по реализации загрузки файлов на сервер без перезагрузки страницы на PHP + Javascript

Проблема

Недавно я столкнулся с вполне, на мой взгляд, распространённой задачей: нужно обеспечить пользователю возможность загрузить на сервер любое число, скажем, картинок с комментарием к каждой из них в рамках одного интерфейса. В моём случае это было: фото товара, его описание и количество. Для наглядности прикладываю скриншот интерфейса:

Идея и алгоритм решения

Так как описания и фотографии для получения конечного результата можно изменять очень много раз, решено было осуществить следующую схему работы: фотографии загружаются на сервер на одной при клике на фото-иконку, при этом в случае успеха сервер возвращает имя картинки, а при неуспехе — «error». Соответственно, в случае успеха, фото-иконка заменяется на миниатюру загруженного фото, а в скрытое поле формы соответствующей строки сохраняется её имя, а при неуспехе мы получаем фото-иконку и пустое скрытое поле формы соответствующей строки, отвечающее за имя фото. Текстовая же информация при изменении любого поля формы отправляется на сервер вся в формате массив [имяФото, описаниеДетали, количествоШт] — это наиболее универсально: один и тот же метод отвечает за полное обновление списка товаров при их редактировании или удалении. Как известно, AJAX не умеет отправлять файлы, поэтому реализуем процедуру загрузки с помощью обычной формы, в качестве target которой укажем скрытый фрейм, который и будет перезагружаться вместо страницы.

Практическая реализация

Итак, в нашем распоряжении HTML, PHP и Javascript. Поехали:

1. Верстаем на странице форму для загрузки фото. Она содержит только один input, который мы спрячем с помощью css:

2. Создадим на странице скрытый iframe, который и будет перезагружаться в результате отправки формы с файлом:

3. Верстаем таблицу товаров, с которой и будет работать пользователь:

В строке товара мы имеем:

— иконка, клик которой будет имитировать клик /> в форме загрузки фото,

— это наш скрытый input, отвечающий за имя фото,

— описание,

— количество штук.

3. Пишем PHP-код загрузки файла:

Мой проект на CodeIgniter, поэтому код вот такой, но в целом, суть в следующем: мы просто загружаем и переименовываем полученный из формы файл, если всё проходит успешно, выводим в наш iframe его имя, если нет — «error».

4. Пишем Javascript, который будет контролировать весь процесс:

Вот тут объясню подробнее:

— просто расставляет порядковые номера в таблице,

— отправляет на сервер все текстовые поля нашей таблицы товаров. Их обработку в рамках этой статьи упоминать смысла нет,

— указываем переменные, которые будут содержать ссылку на текущее фото и таймер. Подробнее об этом чуть позже;

— одна из основных функций: отвечает за обработку результата загрузки фото на основе содержимого нашего скрытого iframe. Эта функцию запускается с интервалом при отправке формы фото и заканчивает своё выполнение подстановкой миниатюры фото вместо фото иконки или выдачей сообщения об ошибке при обнаружении изменения содержимого iframe, то есть по окончании обработки фото сервером;

— просто расставляет порядковые номера в таблице при загрузке страницы — я не включил в статью то, что эта страница используется как при первом добавлении товаров в список, так и при редактировании этого списка, то есть таблица товаров может быть изначально не пустой;

— эмулируем клик input file в форме загрузки изображения при клике фото-иконки (так как пользователь может передумать использовать ранее загруженное фото, очищаем его перед выбором следующего);

— отправляем форму загрузки фото на сервер при изменении поля фото;

— вызываем с интервалом вышеописанную функцию обработки результата загрузки фото на сервер;

— при изменении любого поля (в том числе и имени фото) в списке товаров отправляем его весь на сервер;

— добавляет строку в таблицу товаров;

— удаляет строку из таблицы товаров.

 

Источник: https://habrahabr.ru/post/256197/

https://corp2.info/razrabotka-i-sozdanie-sajtov-internet-magazinov-veb-proektov-kiev-1038.html

Be the first to comment

Leave a Reply

Your email address will not be published.


*