67
FileAPI: Загрузка и обработка файлов Константин Лебедев https://github.com/mailru/FileAPI

FrontTalks: Константин Лебедев (Mail.ru), File API: обработка файлов на клиенте и их загрузка на сервер

  • Upload
    yandex

  • View
    1.179

  • Download
    12

Embed Size (px)

DESCRIPTION

История появления open source библиотеки для работы с файлами. Создание предпросмотра изображений на клиенте. Чтение файлов (exif, id3 и т.п.), загрузка результата на сервер. Всё это работает даже в IE6.

Citation preview

Page 1: FrontTalks: Константин Лебедев (Mail.ru), File API: обработка файлов на клиенте и их загрузка на сервер

FileAPI: Загрузка и обработка файловКонстантин Лебедев

https://github.com/mailru/FileAPI

Page 2: FrontTalks: Константин Лебедев (Mail.ru), File API: обработка файлов на клиенте и их загрузка на сервер

2

Что было

Page 3: FrontTalks: Константин Лебедев (Mail.ru), File API: обработка файлов на клиенте и их загрузка на сервер

3

Что было

Page 4: FrontTalks: Константин Лебедев (Mail.ru), File API: обработка файлов на клиенте и их загрузка на сервер

4

Что было

Flash

Page 5: FrontTalks: Константин Лебедев (Mail.ru), File API: обработка файлов на клиенте и их загрузка на сервер

5

Что было

HTML/JS

Page 6: FrontTalks: Константин Лебедев (Mail.ru), File API: обработка файлов на клиенте и их загрузка на сервер

6

• Множественный выбор файлов

• Получение информации (название, размер, тип)

• Создание пред-просмотра на клиенте

• Масштабирование, кадрирование и поворот

• Загрузка на сервер + CORS

Требования

Page 7: FrontTalks: Константин Лебедев (Mail.ru), File API: обработка файлов на клиенте и их загрузка на сервер

7

• Не зависеть от вёрстки

• Никакой бизнес-логики

• Расширяемость

• Самодостаточность

Требования

Page 8: FrontTalks: Константин Лебедев (Mail.ru), File API: обработка файлов на клиенте и их загрузка на сервер
Page 9: FrontTalks: Константин Лебедев (Mail.ru), File API: обработка файлов на клиенте и их загрузка на сервер

Error #2038

10%

Page 10: FrontTalks: Константин Лебедев (Mail.ru), File API: обработка файлов на клиенте и их загрузка на сервер

Error #2038

5%

Page 11: FrontTalks: Константин Лебедев (Mail.ru), File API: обработка файлов на клиенте и их загрузка на сервер

11

Поддержка

• Chrome 10+• FireFox 3.6+• Opera 11.1+• Safari 5.4+

Page 12: FrontTalks: Константин Лебедев (Mail.ru), File API: обработка файлов на клиенте и их загрузка на сервер

12

Page 13: FrontTalks: Константин Лебедев (Mail.ru), File API: обработка файлов на клиенте и их загрузка на сервер

13

ПОЛУЧЕНИЕ СПИСКАФАЙЛОВ

Page 14: FrontTalks: Константин Лебедев (Mail.ru), File API: обработка файлов на клиенте и их загрузка на сервер

14

HTML5

<input id="file" type="file" multiple /><script>

var input = document.getByElementId("file"); input.addEventListener("change", function (){

var files = input.files; }, false);

</script>

Page 15: FrontTalks: Константин Лебедев (Mail.ru), File API: обработка файлов на клиенте и их загрузка на сервер

15

HTML5

<input id="file" type="file" multiple /><script>

var input = document.getByElementId("file"); input.addEventListener("change", function (){

var files = input.files; }, false);

</script>

Page 16: FrontTalks: Константин Лебедев (Mail.ru), File API: обработка файлов на клиенте и их загрузка на сервер

16

HTML5

<input id="file" type="file" multiple /><script>

var input = document.getByElementId("file"); input.addEventListener("change", function (){

var files = input.files; }, false);

</script>

Page 17: FrontTalks: Константин Лебедев (Mail.ru), File API: обработка файлов на клиенте и их загрузка на сервер

17

Flash

FLASH

Page 18: FrontTalks: Константин Лебедев (Mail.ru), File API: обработка файлов на клиенте и их загрузка на сервер

18

Flash

FLASH

Page 19: FrontTalks: Константин Лебедев (Mail.ru), File API: обработка файлов на клиенте и их загрузка на сервер

19

Flash

FLASH

Flash --> jsFunc([{ id: "346515436346", // уникальный идентификатор

name: "hello-world.png", // название файла type: "image/png", // mime-type

size: 43325 // рамер}, {

// etc.}])

Page 20: FrontTalks: Константин Лебедев (Mail.ru), File API: обработка файлов на клиенте и их загрузка на сервер

Взаимодействие

flash.cmd("imageTransform", { id: "346515436346", // идентификатор файла

matrix: { }, // "матрица" трансформации callback: "__UNIQ_NAME__" // размер

});

Page 21: FrontTalks: Константин Лебедев (Mail.ru), File API: обработка файлов на клиенте и их загрузка на сервер

21

API<span class="js-fileapi-wrapper" style="position: relative">

<input id="file" type="file" multiple /></span><script>

var input = document.getByElementId("file"); FileAPI.event.on(input, "change", function (){

var files = FileAPI.getFiles(input); });

</script>

Page 22: FrontTalks: Константин Лебедев (Mail.ru), File API: обработка файлов на клиенте и их загрузка на сервер

22

API<span class="js-fileapi-wrapper" style="position: relative">

<input id="file" type="file" multiple /></span><script>

var input = document.getByElementId("file"); FileAPI.event.on(input, "change", function (evt){

var files = FileAPI.getFiles(evt); });

</script>

Page 23: FrontTalks: Константин Лебедев (Mail.ru), File API: обработка файлов на клиенте и их загрузка на сервер

23

ФИЛЬТРАЦИЯ

Page 24: FrontTalks: Константин Лебедев (Mail.ru), File API: обработка файлов на клиенте и их загрузка на сервер

FileReader

• readAsDataURL(file)

• readAsArrayBuffer(file)

• readAsText(file[, encoding])

Page 25: FrontTalks: Константин Лебедев (Mail.ru), File API: обработка файлов на клиенте и их загрузка на сервер

25

ФильтрацияFileAPI.filterFiles(files, function (file, info){

return file.size < 10 * FileAPI.MB;

}, function (files, ignore){

if( files.length > 0 ){

// ...

}

});

Page 26: FrontTalks: Константин Лебедев (Mail.ru), File API: обработка файлов на клиенте и их загрузка на сервер

FileAPI.addInfoReader(/^audio/, function (file, callback){ // собираем нужную информацию

// и возвращаем её

callback( false, // или текст ошибки

{ artist: "...", album: "...", title: "...", ... } );});

Информация о файле

Page 27: FrontTalks: Константин Лебедев (Mail.ru), File API: обработка файлов на клиенте и их загрузка на сервер

FileAPI.getInfo(audioFile, function (err, tags){ if( !err ){

var li = document.createElement("li"); li.innerHTML = tags.artist +" – "+ tags.title;

ul.appendChild(li); }});

Информация о файле

Page 28: FrontTalks: Константин Лебедев (Mail.ru), File API: обработка файлов на клиенте и их загрузка на сервер

ПРЕДПРОСМОТР

Page 29: FrontTalks: Константин Лебедев (Mail.ru), File API: обработка файлов на клиенте и их загрузка на сервер

Предпросмотр

DataURI

Page 30: FrontTalks: Константин Лебедев (Mail.ru), File API: обработка файлов на клиенте и их загрузка на сервер

Предпросмотр

DataURI

Base64

Page 31: FrontTalks: Константин Лебедев (Mail.ru), File API: обработка файлов на клиенте и их загрузка на сервер

Предпросмотр

DataURI

Base64

“data:image/png;base64,” + Base64

<img/>

Page 32: FrontTalks: Константин Лебедев (Mail.ru), File API: обработка файлов на клиенте и их загрузка на сервер

Предпросмотр

DataURI

Base64

“data:image/png;base64,” + Base64

Base64

<img/>

Page 33: FrontTalks: Константин Лебедев (Mail.ru), File API: обработка файлов на клиенте и их загрузка на сервер

Предпросмотр

HTML5• FileReader.readAsDataURL(file) — позволяет

прочесть содержимое файла как DataURL• URL.createObjectURL(file) — создает ссылку,

указывающую на файл

Page 34: FrontTalks: Константин Лебедев (Mail.ru), File API: обработка файлов на клиенте и их загрузка на сервер

Предпросмотр

HTML5• FileReader.readAsDataURL(file) — позволяет

прочесть содержимое файла как DataURL• URL.createObjectURL(file) — создает ссылку,

указывающую на файл• URL.revokeObjectURL(file) — убрать ссылку

Page 35: FrontTalks: Константин Лебедев (Mail.ru), File API: обработка файлов на клиенте и их загрузка на сервер

35

• crop(x, y, width, height) — кадрирование

• resize(width[, height]) — масштабирование

• rotate(deg) — поворот

• preview(width, height) — кадрирует и масштабирует

• get(callback) — получить итоговое изображение

FileAPI.Image

Page 36: FrontTalks: Константин Лебедев (Mail.ru), File API: обработка файлов на клиенте и их загрузка на сервер

36

Matrix{ // параметры фрагмента оригинала

sx: Number, sy: Number, sw: Number, sh: Number,

// требуемые размеры dw: Number, dh: Number, deg: Number

}

Page 37: FrontTalks: Константин Лебедев (Mail.ru), File API: обработка файлов на клиенте и их загрузка на сервер

37

FileAPI.Image

FileAPI.Image(imageFle) .crop(300, 300)

.resize(100, 100) .get(function (err, img){

if( !err ){ images.appendChild(img);

} });

Page 38: FrontTalks: Константин Лебедев (Mail.ru), File API: обработка файлов на клиенте и их загрузка на сервер

Сжатие

5197х4987

Page 39: FrontTalks: Константин Лебедев (Mail.ru), File API: обработка файлов на клиенте и их загрузка на сервер

Сжатие

Page 40: FrontTalks: Константин Лебедев (Mail.ru), File API: обработка файлов на клиенте и их загрузка на сервер

Сжатие

5197х4987 2598х2493

Page 41: FrontTalks: Константин Лебедев (Mail.ru), File API: обработка файлов на клиенте и их загрузка на сервер

Сжатие x 2

5197х4987 2598х2493 1299х1246

Page 42: FrontTalks: Константин Лебедев (Mail.ru), File API: обработка файлов на клиенте и их загрузка на сервер

Сжатие x 5

5197х4987 2598х2493 1299х1246

100х100

Page 43: FrontTalks: Константин Лебедев (Mail.ru), File API: обработка файлов на клиенте и их загрузка на сервер

Сжатие

Серия

Page 44: FrontTalks: Константин Лебедев (Mail.ru), File API: обработка файлов на клиенте и их загрузка на сервер

ЗАГРУЗКА ФАЙЛОВ

Page 45: FrontTalks: Константин Лебедев (Mail.ru), File API: обработка файлов на клиенте и их загрузка на сервер

Загрузка

<form action="/upload" method="post"

enctype="multipart/form-data"> <input name="files" type="file" />

<input name="foo" value="bar" type="hidden" /></form>

Page 46: FrontTalks: Константин Лебедев (Mail.ru), File API: обработка файлов на клиенте и их загрузка на сервер

Загрузка

<form target="__UNIQ__" action="/upload" method="post"

enctype="multipart/form-data"> <iframe name="__UNIQ__"></iframe>

<input name="files" type="file" /> <input name="foo" value="bar" type="hidden" />

</form>

Уникальный идентификатор

Page 47: FrontTalks: Константин Лебедев (Mail.ru), File API: обработка файлов на клиенте и их загрузка на сервер

Загрузка

XMLHttpRequest level 2

FormData

Page 48: FrontTalks: Константин Лебедев (Mail.ru), File API: обработка файлов на клиенте и их загрузка на сервер

Загрузка

// собираем данные для отправкиvar form = new FormDataform.append("foo", "bar");form.append("attach", file);

// отправояем на серверvar xhr = new XMLHttpRequest;

xhr.open("POST", "/upload", true);xhr.send(form)

Page 49: FrontTalks: Константин Лебедев (Mail.ru), File API: обработка файлов на клиенте и их загрузка на сервер

Загрузка

// собираем данные для отправкиvar form = new FormDataform.append("foo", "bar");form.append("attach", file);

// отправояем на серверvar xhr = new XMLHttpRequest;

xhr.open("POST", "/upload", true);xhr.send(form)

Page 50: FrontTalks: Константин Лебедев (Mail.ru), File API: обработка файлов на клиенте и их загрузка на сервер

ЗагрузкаcanvasToBlob(canvas, function (blob){

// собираем данные для отправкиvar form = new FormDataform.append("foo", "bar");form.append("attach", blob, "filename.png");

// отправляем на серверvar xhr = new XMLHttpRequest;xhr.open("POST", "/upload", true);xhr.send(form)

});

Page 51: FrontTalks: Константин Лебедев (Mail.ru), File API: обработка файлов на клиенте и их загрузка на сервер

Загрузка

<cavnas/> DataURL

dataURL = canvas.toDataURL(“image/png”);

Page 52: FrontTalks: Константин Лебедев (Mail.ru), File API: обработка файлов на клиенте и их загрузка на сервер

Загрузка

<cavnas/> DataURL Base64

dataURL = canvas.toDataURL(“image/png”);base64 = dataURL.replace(/^data:[^,]+,/, “”);

Page 53: FrontTalks: Константин Лебедев (Mail.ru), File API: обработка файлов на клиенте и их загрузка на сервер

Загрузка

<cavnas/> DataURL Base64

BinaryString

dataURL = canvas.toDataURL(“image/png”);base64 = dataURL.replace(/^data:[^,]+,/, “”);

binaryString = window.atob(base64);

Page 54: FrontTalks: Константин Лебедев (Mail.ru), File API: обработка файлов на клиенте и их загрузка на сервер

54

Multipart

var uniq = '1234567890';var xhr = new XMLHttpRequest;xhr.open('POST', '/upload', true);

xhr.setRequestHeader('Content-Type', 'multipart/form-data; boundary=_'+uniq);xhr.sendAsBinary([

'--_'+ uniq, 'Content-Disposition: form-data; name="my-file"; filename="hello-world.png"'

, 'Content-Type: image/png', ''

, binaryString, '--_'+ uniq +'--'

].join('\r\n'));

Page 55: FrontTalks: Константин Лебедев (Mail.ru), File API: обработка файлов на клиенте и их загрузка на сервер

55

Загрузкаvar xhr = FileAPI.upload({

url: '/upload', data: { foo: 'bar' },

headers: { 'Session-Id': '...' }, files: { images: imageFiles, others: otherFiles },

imageTransform: { maxWidth: 1024, maxHeight: 768 }, upload: function (xhr){},

progress: function (event, file){}, complete: function (err, xhr, file){},

fileupload: function (file, xhr){}, fileprogress: function (event, file){},

filecomplete: function (err, xhr, file){}});

Page 56: FrontTalks: Константин Лебедев (Mail.ru), File API: обработка файлов на клиенте и их загрузка на сервер

56

var xhr = FileAPI.upload({ url: '/upload',

data: { foo: 'bar' }, headers: { 'Session-Id': '...' },

files: { images: imageFiles, others: otherFiles }, imageTransform: { maxWidth: 1024, maxHeight: 768 },

upload: function (xhr){}, progress: function (event, file){},

complete: function (err, xhr, file){}, fileupload: function (file, xhr){},

fileprogress: function (event, file){}, filecomplete: function (err, xhr, file){}

});

Загрузка

Page 57: FrontTalks: Константин Лебедев (Mail.ru), File API: обработка файлов на клиенте и их загрузка на сервер

Загрузка

{ huge: { maxWidth: 800, maxHeight: 600, rotate: 90 },

medium: { width: 320, height: 240, preview: true }, small: { width: 100, height: 120, preview: true }

}

imageTransform:

Page 58: FrontTalks: Константин Лебедев (Mail.ru), File API: обработка файлов на клиенте и их загрузка на сервер

58

XHR

var xhr = FileAPI.upload({ … });

Page 59: FrontTalks: Константин Лебедев (Mail.ru), File API: обработка файлов на клиенте и их загрузка на сервер

59

XHR

var xhr = FileAPI.upload({ … });

• status — HTTP status code• statusText — HTTP status text• responseText — ответ сервера• getResponseHeader(name) — получить заголовок ответа сервера• getAllResponseHeaders() — получить все заголовки• abort() — отменить загрузку

Page 60: FrontTalks: Константин Лебедев (Mail.ru), File API: обработка файлов на клиенте и их загрузка на сервер

Drag’n’Drop

Перетащите файлы сюда

<div class="dropzone"></div>

Page 61: FrontTalks: Константин Лебедев (Mail.ru), File API: обработка файлов на клиенте и их загрузка на сервер

Drag’n’Drop

4

<div class="dropzone dropzone_hover"></div>

Page 62: FrontTalks: Константин Лебедев (Mail.ru), File API: обработка файлов на клиенте и их загрузка на сервер

Drag’n’Drop<div id="el" class="dropzone"></div>

<script> var el = document.getElementById("el");

FileAPI.event.dnd(el, function (over){ if( ever ){

el.classList.add("dropzone_hover"); } else {

el.classList.remove("dropzone_hover"); }

}, function (files){ uploadFiles(files);

}); </script>

4

Page 63: FrontTalks: Константин Лебедев (Mail.ru), File API: обработка файлов на клиенте и их загрузка на сервер

Drag’n’Drop<div id="el" class="dropzone"></div>

<script> var el = document.getElementById("el");

FileAPI.event.dnd(el, function (over){ if( ever ){

el.classList.add("dropzone_hover"); } else {

el.classList.remove("dropzone_hover"); }

}, function (files){ uploadFiles(files);

}); </script>

4

Page 64: FrontTalks: Константин Лебедев (Mail.ru), File API: обработка файлов на клиенте и их загрузка на сервер

Drag’n’Drop<div id="el" class="dropzone"></div>

<script> var el = document.getElementById("el");

FileAPI.event.dnd(el, function (over){ if( ever ){

el.classList.add("dropzone_hover"); } else {

el.classList.remove("dropzone_hover"); }

}, function (files){ uploadFiles(files);

}); </script>

4

Page 65: FrontTalks: Константин Лебедев (Mail.ru), File API: обработка файлов на клиенте и их загрузка на сервер

Drag’n’Drop<div id="el" class="dropzone"></div>

<script> var el = document.getElementById("el");

FileAPI.event.dnd(el, function (over){ if( ever ){

el.classList.add("dropzone_hover"); } else {

el.classList.remove("dropzone_hover"); }

}, function (files){ uploadFiles(files);

}); </script>

4

Page 66: FrontTalks: Константин Лебедев (Mail.ru), File API: обработка файлов на клиенте и их загрузка на сервер

Drag’n’Drop

function uploadFiles(dropFiles){ FileAPI.upload({

url: "/upload", files: { attaches: dropFiles },

complete: function (err, xhr){ if( !err ){

// файлы загружены }

} });

}

4

Page 67: FrontTalks: Константин Лебедев (Mail.ru), File API: обработка файлов на клиенте и их загрузка на сервер

Константин ЛебедевJavaScript архитектор[email protected]

https://github.com/mailru/FileAPI