При всем бурном развитии web, и стандартов html в частности, работа  с файлами, практически никогда не менялась. К счастью, с приходом HTML5 и связанных с ним API, сейчас у нас гораздо больше возможностей для работы с файлами, чем когда-либо в предыдущих версиях браузеров(iOS до сих пор нет поддержки File API).

Тип Файл - File

Тип File определен в спецификации File API[1] и является абстрактным представлением файла. Каждый экземпляр File имеет следующие свойства:
 name – имя файла
 size – размер файла в байтах
 type –  MIME тип файла

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

Получение ссылок на файлы

Разумеется, доступ к пользовательским файлам строго запрещен в Интернете, потому как очевидны проблемы с безопасностью личных данных. Вы не хотели бы, чтобы Вы загружали веб-страницу, а затем она сканировала Ваш жесткий диск и выясняла, что там есть полезного. Нужно разрешение от пользователя, чтобы получить доступ к файлам с его компьютера. Тем не менее для веб-страниц чтения файлов разрешено каждый раз, когда пользователь решат что-то загрузить.

 Когда вы используете элемент <input type="file">, Вы даете веб странице (и серверу) разрешение на доступ к файлу.  Так, что первое, как вы можете получить объект File, это поле <input type="file">.

HTML5 определяет файловые ссылки для всех <input type="file"> управления. Эта коллекция FileList, которая представляет собой структуру в виде массива под названием FileList содержащую объекты типа File для каждого выбранного файла в поле <input type="file">  (помните, HTML5 позволяет выбрать несколько файлов в этом элементе управления). Так что в любой момент времени, Вы можете получить доступ к файлам пользователя, которые он  выбрал, с помощью кода вроде этого:

<input type="file" id="your-files" multiple>

и

<script>
var control = document.getElementById("your-files");
control.addEventListener("change", function(event) {
    // Когда происходит изменение элементов управления, значит появились новые файлы
    var i = 0,
        files = control.files,
        len = files.length;

    for (; i < len; i++) {
        console.log("Filename: " + files[i].name);
        console.log("Type: " + files[i].type);
        console.log("Size: " + files[i].size + " bytes");
    }

}, false);
</script>

Этот сравнительно простой код ожидает событие изменения в контроле(<input type="file"> ). Когда событие происходит, это означает, что выбор файла изменился, и код перебирает все объекты типа File и выводит информацию из них. Имейте в виду, что свойство файлов всегда доступны из JavaScript, так что вам не придется ждать следующего изменения, чтобы попытаться сделать что-то другое с ними.

Drag and drop файлов

Доступ к файлам из формы по средствам контролов по-прежнему требует действий пользователей: нахождение и выбора  интересующего файла. К счастью, HTML5 Drag and Drop  предоставляет еще один способ для пользователей, чтобы предоставить доступ к своим файлам: путем простого перетаскивания файлов с рабочего стола в веб-браузер. Все, что вам нужно сделать, чтобы это реализовать отслеживать два события.

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

<div id="your-files"></div>
<script>
var target = document.getElementById("your-files");
target.addEventListener("dragover", function(event) {
    event.preventDefault(); // отменяем действие по умолчанию
}, false);
target.addEventListener("drop", function(event) {
    // отменяем действие по умолчанию
    event.preventDefault();
    var i = 0,
     files = event.dataTransfer.files,
     len = files.length;
     for (; i < len; i++) {
          console.log("Filename: " + files[i].name);
          console.log("Type: " + files[i].type);
          console.log("Size: " + files[i].size + " bytes");
     }
}, false);
</script>

event.dataTransfer.files другой FileList объект, через который вы можете получить доступ, к информации о файлах. Код почти такой же, как и контролами формы и объекты типа File могут быть доступны таким же образом.

AJAX pагрузка файлов

Если у вас есть ссылка на файл, то вы сможете сделать очень удобную вещь: загрузить файл с помощью Ajax. Все это возможно благодаря объекту FormData, которая определен в XMLHttpRequest . Этот объект представляет собой HTML-форму и позволяет добавлять пары ключ-значение, которые будут переданы на сервер с помощью метода append():

var form = new FormData();
form.append("name", "Николай");

Самое замечательное в объекте FormData, что вы можете добавить файл непосредственно к нему, фактически имитируя загрузку файла через HTML-форму. Все, что вам нужно сделать, это добавить в файл ссылки с определенным именем, и браузер сделает все остальное. Для примера:

// Создаем форму с несколькими значениями
var form = new FormData();
form.append("name", "Николай");
form.append("photo", control.files[0]);

// отправляем через xhr
var xhr = new XMLHttpRequest();
xhr.onload = function() {
    console.log("Отправка завершена");
};
xhr.open("post", "/entrypoint", true);
xhr.send(form);

Как только объект FormData передается в send (), надлежащие к его содержимому HTTP заголовки  устанавливаются автоматически. Вам не нужно беспокоиться об установке правильной кодировки формы при использовании файлов, сервер будет работать с полученными файлами, так как если бы  была отправлена​​ обычная HTML форма , читая данные о присланном файле из $_FILES['photo'] и текстовыt данных из $_POST['name']. Это дает вам универсальность, чтобы написать код обработки на стороне сервера, который может легко работать как с традиционными HTML-формами так и с формами присланными через Ajax.

И все это работает на последней версии большинства браузеров, включая Internet Explorer 10. К сожалению Internet Explorer 9 этого пока не поддерживает. 

Что дальше

Теперь вы знаете два способа доступа к информации о файле в браузере: через контрол формы и через нативный 'drag and drop'. Вероятно, появятся и другие способы доступа к файлам в будущем, но сейчас Вам нужно знать только эти два. Конечно, читать информацию о файлах, это только часть проблемы.Следующим шагом будет чтение  данных из этих файлов, об этом и напишу во второй части статьи.

Ссылки по теме:

File API спецификация

HTML5 Drag and Drop

XMLHttpRequest Level 2

 

Связанные статьи

Работа с файлами в JavaScript, Часть 2: FileReader
Работа с файлами в JavaScript, Часть 3:Событие прогресса и ошибки
Работа с файлами в JavaScript, Часть 4:Объект URL

Оригинал статьи: http://www.nczonline.net/blog/2012/05/08/working-with-files-in-javascript-part-1/

Оставлять комментарии могут только зарегистрированные пользователи

Комментарии  

Vldimir
# Vldimir 06.06.2013 08:30
Это всё замечательно, но НИКАК не работатет в IE8!!!
Skoder
# Skoder 06.06.2013 17:18
в топку все устаревшие браузеры, они тянут веб вниз
Элчин
# Элчин 22.10.2017 18:00
Привет Вам с 2017! IE8 умер!
Andrej
# Andrej 08.08.2013 20:25
а такой глупый вопрос, а как javascript вынести в отдельный файл?
dlipov
# dlipov 28.08.2013 19:29
просто выносишь его в другой файл, а на нужной странице подключаешь через html тег:

<script type="text/javascript" src="tvoi_fail.js"></script>


и вызываешь уже нужные функции в коде.
Саныч
# Саныч 12.10.2013 04:15
Большое спасибо вам! Я теперь понял принцип отправки файл через ajax. Огромное вам спасибо!
Roma-IT
# Roma-IT 15.01.2014 19:23
Спасибо за лаконичность — это одно из лучших руководств, которые я нашел. Разве, что drag'n'drop я бы поставил в самом конце статьи.



Кстати, у вас крайне сложно оставить комментарий из-за странных ограничений на имя пользователя.
guundu
# guundu 03.11.2014 18:50
new FormData();

Нужно выбранный txt загрузить на сервер и по событию окончания загрузки сразу же и вывести на той же ajax странице в div.



<input type="file>



Проблема с обработчиком php.

Этот "дежурный вариант" работает для обычных форм - и есть зародыш моих знаний:

<?php

move_uploaded_file($_FILES["filename"]["tmp_name"], "./".$_FILES["filename"]["name"]);

?>



Пожалуйста помогите - данного решения видимо нету, все статьи один в один про прогресс-барз.

Мне надо ивент загрузки "on upload" файла на сервер.

if (move... ){

file_get_contents("./".$_FILES["filename"]["name"]);

}

Насколько понимаю - где-то так?



В какой-то статье в Интернет я читал, что можно submit убирать. Но если даже и использовать onsubmit, то этот ивент происходит на клиентской стороне.

И вообще минимальная реализация, txt -> [div] прямо по выбору в <input type="file"> - не должна быть длинная?

Вы как - видите решение?



<div id="iiii"> </div>

<form id="f">

<input type="file" name="filename">

</form>

<script>

var fd=new FormData(document.getElementById("f"));

j=new XMLHttpRequest();

j.open("POST", "upld.php",true);

j.send(f);

j.onreadystatechange=function(){document.getElementById("iiii").textContent=j.responseText;}

</script>
Кирилл Кулеш
# Кирилл Кулеш 05.02.2016 00:26
Отличная статья!
Adamastor
# Adamastor 12.06.2016 16:57
Здравствуйте уважаемые посетители сайта!

Никак не могу сохранить бинарные данные на стороне своего сервера. Не могу понять как их правильно извлечь в PHP скрипте, или, возможно, дело в чем-то другом о чем я не догадываюсь. Пробовал бинарные данные упаковывать в контейнер Blob, может попробовать в ArrayBuffer? Методом POST на сервер отсылается объект 'Blob' или 'ArrayBuffer', может надо обратится к каким-либо его свойтвам дабы извлечь данные?

Суть схемы в том чтобы с помощью XHR запроса получить аудио файл в формате MP3 и в последствии записать (спарсить) его себе на сервер.

Ссылка на файл с JS и PHP скриптами: http://file.sampo.ru/2rjjsf/

Помогите пожалуйста!

Зарание благодарен! С уважением, Олег.
PROPHESSOR
# PROPHESSOR 24.07.2017 17:28
AJAX pагрузка файлов
por1122
# por1122 07.07.2022 18:02
ช่วยตัวเอง ให้มีเงิน Slot Pgเรามาลองมาดูกันว่าถ้าอยากมีเงินเก็บมากขึ้นเพื่อสร้ างความมั่นคงให้กับชีวิต ทุกคนล้วนคาดหวังให้ตัวเองส ุขสบาย ลอง slot pg มีกิน มีเงินใช้จนถึงวันสุดท้าย ของชีวิต
pg slot
# pg slot 27.01.2023 04:39
slotgxy888v5

pg slot, mother website, big website, easy to deposit, withdraw, trust 99.99% for sure. Visit our website. slotgxy888 pg slot
pg slot
# pg slot 27.01.2023 05:21
Try playing [pg slot->https://www.slotgxy888.com/] games, apply for slot games, direct web, free games, free slots, free trial, withdraw today. The website has collected more than 100 interesting slot games for everyone to try for free. The hottest online slot game Guaranteed fun without boredom