константин лебедев

Post on 22-Jun-2015

3.327 Views

Category:

Documents

1 Downloads

Preview:

Click to see full reader

TRANSCRIPT

FileAPI: Загрузка и обработка файлов

Константин Лебедевhttps://github.com/mailru/FileAPI

3

Что было

4

Что было

5

Что было

Flash

6

Что было

HTML/JS

7

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

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

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

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

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

Требования

8

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

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

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

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

Требования

Error #2038

10%

Error #2038

5%

12

Поддержка

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

13

14

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

15

HTML5

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

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

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

</script>

16

HTML5

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

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

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

</script>

17

HTML5

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

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

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

</script>

18

Flash

FLASH

19

Flash

FLASH

20

Flash

FLASH

Flash --> jsFunc([{id: "346515436346", // уникальный идентификаторname: "hello-world.png", // название файлаtype: "image/png", // mime-typesize: 43325 // рамер

}, { // etc.}])

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

flash.cmd("imageTransform", {id: "346515436346", // идентификатор файлаmatrix: { }, // "матрица" трансформацииcallback: "__UNIQ_NAME__" // размер

});

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 (){

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

</script>

23

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);}, false);

</script>

24

ФИЛЬТРАЦИЯ

FileReader

• readAsDataURL(file)

• readAsBinaryString(file)

• readAsArrayBuffer(file)

• readAsText(file[, encoding])

26

Фильтрация

FileAPI.filterFiles(files, function (file, info){

return file.size < 10 * FileAPI.MB;

}, function (files, ignore){

if( files.length > 0 ){

// ...

}

});

FileAPI.addInfoReader(/^audio/, function (file, callback){

// собираем нужную информацию

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

callback(

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

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

);

});

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

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

if( !err ){

var li = document.createElement("li");

li.innerHTML = tags.artist +" – "+ tags.title;

ul.appendChild(li);

}

});

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

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

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

DataURI

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

DataURI

Base64

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

DataURI

Base64

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

<img/>

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

DataURI

Base64

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

Base64

<img/>

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

HTML5

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

прочесть содержимое файла как DataURL

• URL.createObjectURL(file) — создает ссылку,

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

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

HTML5

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

прочесть содержимое файла как DataURL

• URL.createObjectURL(file) — создает ссылку,

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

• URL.revokeObjectURL(file) — убрать ссылку

36

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

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

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

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

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

FileAPI.Image

37

Matrix

{ // параметры фрагмента оригинала sx: Number,sy: Number,sw: Number,sh: Number,

// требуемые размеры

dw: Number,dh: Number,deg: Number

}

38

FileAPI.Image

FileAPI.Image(imageFle).crop(300, 300).resize(100, 100).get(function (err, img){

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

}})

;

Сжатие

5197х4987

Сжатие

Сжатие

5197х4987 2598х2493

Сжатие x 2

5197х4987 2598х2493 1299х1246

Сжатие x 5

5197х4987 2598х2493 1299х1246

100х100

Сжатие

Серия

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

• Без обновления страницы

• Процесс загрузки

• Получить ответ от сервера

Требования

Загрузка

<form action="/upload" method="post" enctype="multipart/form-data">

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

</form>

Загрузка

<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>

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

Загрузка

XMLHttpRequest level 2

FormData

Загрузка

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

var form = new FormDataform.append("foo", "bar");form.append("attach", file);

// отправояем на сервер

var xhr = new XMLHttpRequest;xhr.open("POST", "/upload", true);xhr.send(form)

Загрузка

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

var form = new FormDataform.append("foo", "bar");form.append("attach", file);

// отправляем на сервер

var xhr = new XMLHttpRequest;xhr.open("POST", "/upload", true);xhr.send(form)

Загрузка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)

});

Загрузка

<cavnas/> DataURL

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

Загрузка

<cavnas/> DataURL Base64

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

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

Загрузка

<cavnas/> DataURL Base64

BinaryString

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

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

binaryString = window.atob(base64);

56

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'));

57

Загрузка

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){}});

58

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){}});

Загрузка

Загрузка

{

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

medium: { width: 320, height: 240, preview: true },

small: { width: 100, height: 120, preview: true }

}

imageTransform:

60

XHR

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

61

XHR

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

• status — HTTP status code

• statusText — HTTP status text

• responseText — ответ сервера

• getResponseHeader(name) — получить заголовок ответа сервера

• getAllResponseHeaders() — получить все заголовки

• abort() — отменить загрузку

Drag’n’Drop

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

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

Drag’n’Drop

4

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

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

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

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

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

Drag’n’Drop

function uploadFiles(dropFiles){ FileAPI.upload({ url: "/upload", files: { attaches: dropFiles }, complete: function (err, xhr){ if( !err ){ // файлы загружены } } }); }

4

Константин ЛебедевJavaScript архитекторk.lebedev@corp.mail.ru

https://github.com/mailru/FileAPI

top related