Как быть если нужно сделать превью, т.е. предпросмотр, какого-либо изображения на веб-странице, но нежелательно грузить само изображение или файл, где оно находится, с локального компьютера на сервер-хост, где и находится код HTML5/CSS3/JS данной страницы?
Например, это могут быть личные фотографии, или изображения очень большого объёма, которые загрузят канал, или другие соображения не делиться информацией с сервером. А может наоборот, нежелание предоставлять возможность загрузить сервер всяким хламом.
Во всех таких случаях нужно обрабатывать изображения на компьютере пользователя.
Как это работало раньше и работает сейчас.
В стандартном HTML для выбора файла или файлов на локальном компьютере есть тэг <input type=”file” multiple>, например:
<h3>Выбор нескольких файлов:</h3>
<form action="/action_page.php">
<label for="myfile">Выберите файлы:</label>
<input type="file" id="myfile" name="myfile" multiple><br>
<input type="submit">
</form>
Посмотрим, как это будет выглядеть в различных браузерах.
(При вызове этой формы на смартфоне она вообще пытается записать с камеры... Статья касается только работы на ПК.)
Видно, что расположение кнопок, надписи на кнопках и тексты предоределены, разные для разных браузеров, язык надписей зависит от языка браузера или ОС или данного пользователя, и эти тексты никак нельзя поменять. Тэг <button>, который позволяет создавать дизайнерские кнопки с надписями и картинками, имеет только разрешённые типы button, reset, submit. Это значит, мы сможем менять только кнопку submit, но не file.
Выберем два файла, к примеру:
После выбора форма пишет о том, что два файла выбраны:
Если мы нажмём кнопку «Submit» формы, имена выбранных файлов отправятся на сервер, и программа на сервере (в примере это "/action_page.php">) обработает данные, например, загрузит файлы на сервер.
Если бы мы, к примеру, выбрали только один файл, имя этого файла было бы также показано справа от кнопки:
Как можно добыть больше информации о файле в стандартном JavaScript.
С помощью языка JavaScript и модели DOM можно получить больше информации о любом объекте HTML на странице.
DOM (от англ. Document Object Model — «объектная модель документа») — это программный интерфейс, позволяющий скриптам получить доступ к содержимому HTML-документов, а также изменять их. До HTML5 версии DOMа различались для разных браузеров, но сейчас это стандарт.
Элементу <input type=”file”> соответствует объект DOM в JavaScript: Input FileUpload Object.
Поставить в соответствие объект и кнопку можно, как обычно, через Ид:
<input type="file" id="myFile" onchange=\"myfunction ()\">
<script>
myfunction() { /* обработать один файл, т.к. нет атрибута multiple */
var oFileUpload = document.getElementById("myFile");
// …….
}
</script>
После выбора файла или файлов этот объект содержит, среди прочего,
oFileUpload.value – путь и имя 1-го файла в списке. Когда-то на заре интернета, может быть, это и было так. Сейчас некоторые браузеры содержат только имя файла, другие, например Google Chrome, MS Edge или FireFox, добавляют один и тот же фиктивный путь C:\fakepath\
oFileUpload.files[] – псевдомассив с выбранными файлами, начиная с индекса [0] если выбран единственный файл. Он относится к File API, также ставшему стандартом в HTML5, и содержит побольше информации, такой как имя файла, тип, размер и др. Например:
for (let i = 0; i < oFileUpload.files.length; i++) {
const file = oFileUpload.files[i];
console.log(file.name); // file name
console.log(file.size); // file size in bytes
console.log(file.type); // file type (e.g. "image/jpeg")
}
И как, наконец, можно сделать превью изображения без загрузки на сервер.
Объект FileReader из File API служит для чтения файла. Единственная сложность - данные передаются в асинхронном режиме при помощи событий, так как чтение с диска может занять время, особенно для бальших файлов. Но если выбирать и читать один файл, а не массив файлов (т.е. нет атрибута multiple в тэге <input>), то код не сильно усложняется:
HTML (мы хотим сделать превью выбранного файла в квадрате 100x100):
<img id="uploadPreview" style="width: 100px; height: 100px;">
<input id="uploadImage" type="file" onchange="PreviewImage();">
JavaScript:
function PreviewImage() {
var oFReader = new FileReader(); //никаких аргументов не нужно
oFReader.readAsDataURL(document.getElementById("uploadImage").files[0]);
oFReader.onload = function (oFREvent) {
document.getElementById("uploadPreview").src = oFREvent.target.result;
};
};
Как видите, всё очень просто. Только надо помнить, из-за асинхронного режима обработки события oFReader.onload внутри функции-обработчика все локальные переменные недоступны.
Кроме readAsDataURL, подходящего для подстановки в src для изображения, доступны ещё полезные методы:
· readAsArrayBuffer – для бинарных файлов, для работы с байтами и бинарными данными.
· readAsText – для текстовых файлов, когда мы хотим получить текст в читаемом виде.
Пример использования данной функциональности (превью изображения без загрузки на сервер) можно посмотреть в статье:
-----
Донаты.
Вы можете поблагодарить и поощрить автора денежным подарком через Юmoney на кошелёк 4100117793355888.