- New Tricks in XMLHttpRequest2
- Вступ
- витяг даних
- Вказівка формату відповіді
- Відповіді в форматі ArrayBuffer
- Відповіді в форматі Blob
- Відправка даних
- Відправка строкових даних: xhr.send (DOMString)
- Відправлення файлу або об'єкта Blob: xhr.send (Blob)
- Відправка довільного набору байтів: xhr.send (ArrayBuffer)
- Обмін ресурсами із запитом походження (Cross Origin Resource Sharing, або CORS)
- Включення CORS-запитів
- Створення крос-доменного запиту
- практичні приклади
- Відправлення файлу по частинах
- Корисні посилання
- Вступ
- витяг даних
- Вказівка формату відповіді
- Відповіді в форматі ArrayBuffer
- Відповіді в форматі Blob
- Відправка даних
- Відправка строкових даних: xhr.send (DOMString)
- Відправлення файлу або об'єкта Blob: xhr.send (Blob)
- Відправка довільного набору байтів: xhr.send (ArrayBuffer)
- Обмін ресурсами із запитом походження (Cross Origin Resource Sharing, або CORS)
- Включення CORS-запитів
- Створення крос-доменного запиту
- практичні приклади
- Відправлення файлу по частинах
- Корисні посилання
- Вступ
- витяг даних
- Вказівка формату відповіді
- Відповіді в форматі ArrayBuffer
- Відповіді в форматі Blob
- Відправка даних
- Відправка строкових даних: xhr.send (DOMString)
- Відправлення файлу або об'єкта Blob: xhr.send (Blob)
- Відправка довільного набору байтів: xhr.send (ArrayBuffer)
- Обмін ресурсами із запитом походження (Cross Origin Resource Sharing, або CORS)
- Включення CORS-запитів
- Створення крос-доменного запиту
- практичні приклади
- Відправлення файлу по частинах
- Корисні посилання
- Вступ
- витяг даних
- Вказівка формату відповіді
- Відповіді в форматі ArrayBuffer
- Відповіді в форматі Blob
- Відправка даних
- Відправка строкових даних: xhr.send (DOMString)
- Відправлення файлу або об'єкта Blob: xhr.send (Blob)
- Відправка довільного набору байтів: xhr.send (ArrayBuffer)
- Обмін ресурсами із запитом походження (Cross Origin Resource Sharing, або CORS)
- Включення CORS-запитів
- Створення крос-доменного запиту
- практичні приклади
- Відправлення файлу по частинах
- Корисні посилання
- Вступ
- витяг даних
- Вказівка формату відповіді
- Відповіді в форматі ArrayBuffer
- Відповіді в форматі Blob
- Відправка даних
- Відправка строкових даних: xhr.send (DOMString)
- Відправлення файлу або об'єкта Blob: xhr.send (Blob)
- Відправка довільного набору байтів: xhr.send (ArrayBuffer)
- Обмін ресурсами із запитом походження (Cross Origin Resource Sharing, або CORS)
- Включення CORS-запитів
- Створення крос-доменного запиту
- практичні приклади
- Відправлення файлу по частинах
New Tricks in XMLHttpRequest2
Вступ
Одним з найважливіших елементів в середовищі HTML5 є XMLHttpRequest. Строго кажучи, цей об'єкт не входить в HTML5. Однак він став результатом постійних змін, що вносяться розробниками браузерів в базову платформу. XHR2 грає велику роль, так як є невід'ємною частиною сучасних складних веб-додатків.
Мало хто знає, що в останню версію XHR було додано багато функцій. В XMLHttpRequest Level 2 представлена маса нових можливостей, які позбавлять нас від непотрібних операцій і таких понять, як крос-доменні запити, події ходу відправки файлів, а також підтримка завантаження і відправки двійкових даних. Завдяки цьому технологія AJAX працює в поєднанні з новітніми API HTML5: API файлової системи , API веб-аудіо і WebGL.
У цьому посібнику описано деякі з нових можливостей XMLHttpRequest і особливо ті з них, які необхідні для роботи з файлами .
витяг даних
Завантаження файлу у вигляді довічного об'єкта за допомогою XHR завжди була проблемою. З технічної точки зору це було навіть неможливо. Один з відомих способів полягає в перевизначенні mime-типу користувальницької кодуванням, як показано нижче.
Раніше вміст картинки можна було витягти таким способом:
var xhr = new XMLHttpRequest (); xhr.open ( 'GET', '/path/to/image.png', true); // Hack to pass bytes through unprocessed. xhr.overrideMimeType ( 'text / plain; charset = x-user-defined'); xhr.onreadystatechange = function (e) {if (this.readyState == 4 && this.status == 200) {var binStr = this.responseText; for (var i = 0, len = binStr.length; i <len; ++ i) {var c = binStr.charCodeAt (i); //String.fromCharCode(c & 0xff); var byte = c & 0xff; // byte at offset i}}}; xhr.send ();Цей спосіб працює, проте елемент responseText зовсім не є великим двійковим об'єктом (елементом blob). Це двоичная рядок, що представляє файл картинки. Ми змушуємо сервер повернути дані в необробленому вигляді. Хоча цей прийом працює, я не рекомендую використовувати його. При спробі примусово перевести дані в потрібний формат за допомогою маніпуляцій з кодуванням і рядками завжди виникають проблеми.
Вказівка формату відповіді
У попередньому прикладі картинка завантажувалася у вигляді виконуваного файлу шляхом перевизначення mime-типу сервера і обробки тексту як двійковій рядки. Замість цього скористаємося новими можливостями технології XMLHttpRequest: властивостями responseType і response, що дозволяють вказати браузеру бажаний формат відповіді.
xhr. responseType Перш ніж відправити запит, необхідно задати для властивості xhr.responseType значення text, arraybuffer, blob або document. Зверніть увагу: якщо встановити значення xhr.responseType = '' або опустити його, за замовчуванням вибирається формат text. xhr. response Після успішного виконання запиту властивість response буде містити запитані дані в форматі DOMString, ArrayBuffer, Blob або Document відповідно до значення responseType.Переробимо попередній приклад з використанням цієї нової можливості. Тепер ми витягуємо дані картинки в форматі ArrayBuffer замість рядка. Передаємо буфер в API BlobBuilder і отримуємо об'єкт Blob.
BlobBuilder = window.MozBlobBuilder || window.WebKitBlobBuilder || window.BlobBuilder; var xhr = new XMLHttpRequest (); xhr.open ( 'GET', '/path/to/image.png', true); xhr.responseType = 'arraybuffer'; xhr.onload = function (e) {if (this.status == 200) {var bb = new BlobBuilder (); bb.append (this.response); // Note: not xhr.responseText var blob = bb.getBlob ( 'image / png'); ...}}; xhr.send ();Так набагато краще.
Відповіді в форматі ArrayBuffer
ArrayBuffer - це стандартний контейнер фіксованої довжини для двійкових даних. Це дуже зручний універсальний буфер для необробленої інформації, але його головна перевага - можливість створювати "вистави" вихідних даних за допомогою типізованих масивів JavaScript . Фактично на базі одного джерела ArrayBuffer можна сформувати кілька подань. Наприклад, можна створити 8-бітний цілочисельний масив, який використовує той же об'єкт ArrayBuffer, що і 32-бітний масив на базі тих же даних. Вихідна інформація залишається незмінною: вона просто видається в різному вигляді.
У прикладі нижче ми витягуємо ту ж картинку у форматі ArrayBuffer, але на цей раз створюємо з даних в буфері 8-бітний цілочисельний масив.
var xhr = new XMLHttpRequest (); xhr.open ( 'GET', '/path/to/image.png', true); xhr.responseType = 'arraybuffer'; xhr.onload = function (e) {var uInt8Array = new Uint8Array (this.response); // this.response == uInt8Array.buffer // var byte3 = uInt8Array [4]; // byte at offset 4 ...}; xhr.send ();Відповіді в форматі Blob
Для безпосередньої роботи з об'єктами Blob без операцій з окремими байтами файлу можна використовувати значення xhr.responseType = 'blob'.
window.URL = window.URL || window.webkitURL; // Take care of vendor prefixes. var xhr = new XMLHttpRequest (); xhr.open ( 'GET', '/path/to/image.png', true); xhr.responseType = 'blob'; xhr.onload = function (e) {if (this.status == 200) {var blob = this.response; var img = document.createElement ( 'img'); img.onload = function (e) {window.URL.revokeObjectURL (img.src); // Clean up after yourself. }; img.src = window.URL.createObjectURL (blob); document.body.appendChild (img); ...}}; xhr.send ();Об'єкт Blob можна використовувати по різному: наприклад, зберегти його в індексованої базі даних , Записати в файлову систему HTML5 або створити URL елемента Blob , Як показано в цьому прикладі.
Відправка даних
можливість завантажувати дані в різних форматах дуже важлива, але вона абсолютно непотрібна, якщо ці дані не можна відправити назад (на сервер). До недавнього часу в XMLHttpRequest можна було відправляти тільки дані DOMString або Document (XML). Ситуація змінилась. Перероблений метод send () дозволяє відправляти дані будь-яких типів: DOMString, Document, FormData, Blob, File і ArrayBuffer. Приклади в цій частині розділу ілюструють відправку даних кожного з цих типів.
Відправка строкових даних: xhr.send (DOMString)
function sendText (txt) {var xhr = new XMLHttpRequest (); xhr.open ( 'POST', '/ server', true); xhr.onload = function (e) {if (this.status == 200) {console.log (this.responseText); }}; xhr.send (txt); } SendText ( 'test string'); function sendTextNew (txt) {var xhr = new XMLHttpRequest (); xhr.open ( 'POST', '/ server', true); xhr.responseType = 'text'; xhr.onload = function (e) {if (this.status == 200) {console.log (this.response); }}; xhr.send (txt); } SendText2 ( 'test string');Як бачите, нічого нового. Хоча права частина дещо відрізняється. У ній є рядок responseType = 'text'. Втім, її відсутність не змінює результат.
Багато з нас звикли користуватися плагінами jQuery і іншими бібліотеками для відправки форм AJAX. Замість них можна використовувати FormData - ще один новий тип даних в рамках технології XHR2. Тип FormData дуже зручний для динамічного створення HTML-елементів <form> за допомогою JavaScript. Потім ці форми можна відправити за допомогою AJAX.
function sendForm () {var formData = new FormData (); formData.append ( 'username', 'johndoe'); formData.append ( 'id', 123456); var xhr = new XMLHttpRequest (); xhr.open ( 'POST', '/ server', true); xhr.onload = function (e) {...}; xhr.send (formData); }По суті, ми просто динамічно створюємо елемент <form> і додаємо в неї поля <input> за допомогою методу append.
При цьому форму можна не створювати з нуля. Об'єкти FormData можна форматувати за допомогою існуючих на сторінці елементів HTMLFormElement. наприклад:
<Form id = "myform" name = "myform" action = "/ server"> <input type = "text" name = "username" value = "johndoe"> <input type = "number" name = "id" value = "123456"> <input type = "submit" onclick = "return sendForm (this.form);"> </ form> function sendForm (form) {var formData = new FormData (form); formData.append ( 'secret_token', '1234567890'); // Append extra data before send. var xhr = new XMLHttpRequest (); xhr.open ( 'POST', form.action, true); xhr.onload = function (e) {...}; xhr.send (formData); return false; // Prevent page from submitting. }HTML-форма може містити файли (наприклад, <input type = "file">). Об'єкт FormData теж підтримує цю можливість. Досить просто прикріпити файли, і браузер виконає запит multipart / form-data при виклику методу send ().
function uploadFiles (url, files) {var formData = new FormData (); for (var i = 0, file; file = files [i]; ++ i) {formData.append (file.name, file); } Var xhr = new XMLHttpRequest (); xhr.open ( 'POST', url, true); xhr.onload = function (e) {...}; xhr.send (formData); // multipart / form-data} document.querySelector ( 'input [type = "file"]'). AddEventListener ( 'change', function (e) {uploadFiles ( '/ server', this.files);}, false );Відправлення файлу або об'єкта Blob: xhr.send (Blob)
За допомогою XHR також можна відправити файл або об'єкт Blob. Слід пам'ятати, що файли є об'єктами Blob, тому в наших прикладах між ними немає різниці.
У цьому прикладі ми створюємо новий текстовий файл за допомогою API BlobBuilder і відправляємо цей об'єкт Blob на сервер. Цей код також запускає обробник, який показує нам хід відправки файлу.
<Progress min = "0" max = "100" value = "0"> 0% complete </ progress> function upload (blobOrFile) {var xhr = new XMLHttpRequest (); xhr.open ( 'POST', '/ server', true); xhr.onload = function (e) {...}; // Listen to the upload progress. var progressBar = document.querySelector ( 'progress'); xhr.upload.onprogress = function (e) {if (e.lengthComputable) {progressBar.value = (e.loaded / e.total) * 100; progressBar.textContent = progressBar.value; // Fallback for unsupported browsers. }}; xhr.send (blobOrFile); } // Take care of vendor prefixes. BlobBuilder = window.MozBlobBuilder || window.WebKitBlobBuilder || window.BlobBuilder; var bb = new BlobBuilder (); bb.append ( 'hello world'); upload (bb.getBlob ( 'text / plain'));Відправка довільного набору байтів: xhr.send (ArrayBuffer)
В якості корисних даних XHR також можна відправляти об'єкти ArrayBuffer.
function sendArrayBuffer () {var xhr = new XMLHttpRequest (); xhr.open ( 'POST', '/ server', true); xhr.onload = function (e) {...}; var uInt8Array = new Uint8Array ([1, 2, 3]); xhr.send (uInt8Array.buffer); }Обмін ресурсами із запитом походження (Cross Origin Resource Sharing, або CORS)
За допомогою технології CORS веб-додатки можуть виконувати крос-доменні AJAX-запити до інших доменів. Зробити це дуже просто: достатньо, щоб сервер відправив необхідний заголовок відповіді.
Включення CORS-запитів
Припустимо, додаток знаходиться в домені example.com і потрібно отримати дані з домену www.example2.com. Як правило, при спробі відправити такий AJAX-запит він не виконується, а браузер видає помилку невідповідності походження. Завдяки технології CORS сайт www.example2.com може дозволити програмі з сайту example.com виконувати запити шляхом додавання одного заголовка.
Access-Control-Allow-Origin: http://example.comТема Access-Control-Allow-Origin можна додати як для одного сайту, так і для всього домену. Щоб увімкнути надсилання запитів з усіх доменів, додайте рядок такого виду:
Access-Control-Allow-Origin: *Фактично на всіх сторінках цього сайту (html5rocks.com) також використовується технологія CORS. Запустіть інструменти розробника, і у відповіді ви побачите заголовок Access-Control-Allow-Origin:
Тема Access-Control-Allow-Origin на сайті html5rocks.comДозволити крос-доменні запити нескладно, тому настійно рекомендується включати CORS для загальнодоступних даних.
Створення крос-доменного запиту
Якщо сервер-адресат підтримує CORS, крос-доменний запит нічим не відрізняється від звичайного запиту XMLHttpRequest. Наприклад, ось так маєте змогу надсилати запити з додатка на сервері example.com до сервера www.example2.com:
var xhr = new XMLHttpRequest (); xhr.open ( 'GET', 'http://www.example2.com/hello.json'); xhr.onload = function (e) {var data = JSON.parse (this.response); ...} xhr.send ();практичні приклади
Завантаження і збереження файлів в файлову систему HTML5
Припустимо, у вас є галерея зображень і ви хочете зберегти кілька картинок у себе за допомогою файлової системи HTML5 . Ви можете запросити ці картинки як об'єкти ArrayBuffer, створити на основі цих даних об'єкт Blob і записати його за допомогою FileWriter.
window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem; function onError (e) {console.log ( 'Error', e); } Var xhr = new XMLHttpRequest (); xhr.open ( 'GET', '/path/to/image.png', true); xhr.responseType = 'arraybuffer'; xhr.onload = function (e) {window.requestFileSystem (TEMPORARY, 1024 * 1024, function (fs) {fs.root.getFile ( 'image.png', {create: true}, function (fileEntry) {fileEntry.createWriter (function (writer) {writer.onwrite = function (e) {...}; writer.onerror = function (e) {...}; var bb = new BlobBuilder (); bb.append (xhr.response) ; writer.write (bb.getBlob ( 'image / png'));}, onError);}, onError);}, onError); }; xhr.send ();Зверніть увагу: для використання цього коду потрібно ознайомитися з умовами підтримки браузерів і обмеженнями на зберігання в керівництві Знайомство з API файлової системи .
Відправлення файлу по частинах
API файлів істотно полегшує відправку великих файлів. Методика така: великий файл розбивається на кілька дрібних, які потім відправляються за допомогою XHR і збираються назад на сервері. Приблизно так само Gmail швидко відправляє великі прикріплені файли. Ця технологія також дозволяє обійти обмеження Google App Engine: 32 МБ на один HTTP-запит.
window.BlobBuilder = window.MozBlobBuilder || window.WebKitBlobBuilder || window.BlobBuilder; function upload (blobOrFile) {var xhr = new XMLHttpRequest (); xhr.open ( 'POST', '/ server', true); xhr.onload = function (e) {...}; xhr.send (blobOrFile); } Document.querySelector ( 'input [type = "file"]'). AddEventListener ( 'change', function (e) {var blob = this.files [0]; const BYTES_PER_CHUNK = 1024 * 1024; // 1MB chunk sizes . const SIZE = blob.size; var start = 0; var end = BYTES_PER_CHUNK; while (start <SIZE) {// Note: blob.slice has changed semantics and been prefixed. See http://goo.gl/U9mE5. if ( 'mozSlice' in blob) {var chunk = blob.mozSlice (start, end);} else {var chunk = blob.webkitSlice (start, end);} upload (chunk); start = end; end = start + BYTES_PER_CHUNK;}}, false); }) ();Нижче наведено код для збірки файлу на сервері.
Перевірте, як він працює.
Корисні посилання
New Tricks in XMLHttpRequest2
Вступ
Одним з найважливіших елементів в середовищі HTML5 є XMLHttpRequest. Строго кажучи, цей об'єкт не входить в HTML5. Однак він став результатом постійних змін, що вносяться розробниками браузерів в базову платформу. XHR2 грає велику роль, так як є невід'ємною частиною сучасних складних веб-додатків.
Мало хто знає, що в останню версію XHR було додано багато функцій. В XMLHttpRequest Level 2 представлена маса нових можливостей, які позбавлять нас від непотрібних операцій і таких понять, як крос-доменні запити, події ходу відправки файлів, а також підтримка завантаження і відправки двійкових даних. Завдяки цьому технологія AJAX працює в поєднанні з новітніми API HTML5: API файлової системи , API веб-аудіо і WebGL.
У цьому посібнику описано деякі з нових можливостей XMLHttpRequest і особливо ті з них, які необхідні для роботи з файлами .
витяг даних
Завантаження файлу у вигляді довічного об'єкта за допомогою XHR завжди була проблемою. З технічної точки зору це було навіть неможливо. Один з відомих способів полягає в перевизначенні mime-типу користувальницької кодуванням, як показано нижче.
Раніше вміст картинки можна було витягти таким способом:
var xhr = new XMLHttpRequest (); xhr.open ( 'GET', '/path/to/image.png', true); // Hack to pass bytes through unprocessed. xhr.overrideMimeType ( 'text / plain; charset = x-user-defined'); xhr.onreadystatechange = function (e) {if (this.readyState == 4 && this.status == 200) {var binStr = this.responseText; for (var i = 0, len = binStr.length; i <len; ++ i) {var c = binStr.charCodeAt (i); //String.fromCharCode(c & 0xff); var byte = c & 0xff; // byte at offset i}}}; xhr.send ();Цей спосіб працює, проте елемент responseText зовсім не є великим двійковим об'єктом (елементом blob). Це двоичная рядок, що представляє файл картинки. Ми змушуємо сервер повернути дані в необробленому вигляді. Хоча цей прийом працює, я не рекомендую використовувати його. При спробі примусово перевести дані в потрібний формат за допомогою маніпуляцій з кодуванням і рядками завжди виникають проблеми.
Вказівка формату відповіді
У попередньому прикладі картинка завантажувалася у вигляді виконуваного файлу шляхом перевизначення mime-типу сервера і обробки тексту як двійковій рядки. Замість цього скористаємося новими можливостями технології XMLHttpRequest: властивостями responseType і response, що дозволяють вказати браузеру бажаний формат відповіді.
xhr. responseType Перш ніж відправити запит, необхідно задати для властивості xhr.responseType значення text, arraybuffer, blob або document. Зверніть увагу: якщо встановити значення xhr.responseType = '' або опустити його, за замовчуванням вибирається формат text. xhr. response Після успішного виконання запиту властивість response буде містити запитані дані в форматі DOMString, ArrayBuffer, Blob або Document відповідно до значення responseType.Переробимо попередній приклад з використанням цієї нової можливості. Тепер ми витягуємо дані картинки в форматі ArrayBuffer замість рядка. Передаємо буфер в API BlobBuilder і отримуємо об'єкт Blob.
BlobBuilder = window.MozBlobBuilder || window.WebKitBlobBuilder || window.BlobBuilder; var xhr = new XMLHttpRequest (); xhr.open ( 'GET', '/path/to/image.png', true); xhr.responseType = 'arraybuffer'; xhr.onload = function (e) {if (this.status == 200) {var bb = new BlobBuilder (); bb.append (this.response); // Note: not xhr.responseText var blob = bb.getBlob ( 'image / png'); ...}}; xhr.send ();Так набагато краще.
Відповіді в форматі ArrayBuffer
ArrayBuffer - це стандартний контейнер фіксованої довжини для двійкових даних. Це дуже зручний універсальний буфер для необробленої інформації, але його головна перевага - можливість створювати "вистави" вихідних даних за допомогою типізованих масивів JavaScript . Фактично на базі одного джерела ArrayBuffer можна сформувати кілька подань. Наприклад, можна створити 8-бітний цілочисельний масив, який використовує той же об'єкт ArrayBuffer, що і 32-бітний масив на базі тих же даних. Вихідна інформація залишається незмінною: вона просто видається в різному вигляді.
У прикладі нижче ми витягуємо ту ж картинку у форматі ArrayBuffer, але на цей раз створюємо з даних в буфері 8-бітний цілочисельний масив.
var xhr = new XMLHttpRequest (); xhr.open ( 'GET', '/path/to/image.png', true); xhr.responseType = 'arraybuffer'; xhr.onload = function (e) {var uInt8Array = new Uint8Array (this.response); // this.response == uInt8Array.buffer // var byte3 = uInt8Array [4]; // byte at offset 4 ...}; xhr.send ();Відповіді в форматі Blob
Для безпосередньої роботи з об'єктами Blob без операцій з окремими байтами файлу можна використовувати значення xhr.responseType = 'blob'.
window.URL = window.URL || window.webkitURL; // Take care of vendor prefixes. var xhr = new XMLHttpRequest (); xhr.open ( 'GET', '/path/to/image.png', true); xhr.responseType = 'blob'; xhr.onload = function (e) {if (this.status == 200) {var blob = this.response; var img = document.createElement ( 'img'); img.onload = function (e) {window.URL.revokeObjectURL (img.src); // Clean up after yourself. }; img.src = window.URL.createObjectURL (blob); document.body.appendChild (img); ...}}; xhr.send ();Об'єкт Blob можна використовувати по різному: наприклад, зберегти його в індексованої базі даних , Записати в файлову систему HTML5 або створити URL елемента Blob , Як показано в цьому прикладі.
Відправка даних
можливість завантажувати дані в різних форматах дуже важлива, але вона абсолютно непотрібна, якщо ці дані не можна відправити назад (на сервер). До недавнього часу в XMLHttpRequest можна було відправляти тільки дані DOMString або Document (XML). Ситуація змінилася. Перероблений метод send () дозволяє відправляти дані будь-яких типів: DOMString, Document, FormData, Blob, File і ArrayBuffer. Приклади в цій частині розділу ілюструють відправку даних кожного з цих типів.
Відправка строкових даних: xhr.send (DOMString)
function sendText (txt) {var xhr = new XMLHttpRequest (); xhr.open ( 'POST', '/ server', true); xhr.onload = function (e) {if (this.status == 200) {console.log (this.responseText); }}; xhr.send (txt); } SendText ( 'test string'); function sendTextNew (txt) {var xhr = new XMLHttpRequest (); xhr.open ( 'POST', '/ server', true); xhr.responseType = 'text'; xhr.onload = function (e) {if (this.status == 200) {console.log (this.response); }}; xhr.send (txt); } SendText2 ( 'test string');Як бачите, нічого нового. Хоча права частина дещо відрізняється. У ній є рядок responseType = 'text'. Втім, її відсутність не змінює результат.
Багато з нас звикли користуватися плагінами jQuery і іншими бібліотеками для відправки форм AJAX. Замість них можна використовувати FormData - ще один новий тип даних в рамках технології XHR2. Тип FormData дуже зручний для динамічного створення HTML-елементів <form> за допомогою JavaScript. Потім ці форми можна відправити за допомогою AJAX.
function sendForm () {var formData = new FormData (); formData.append ( 'username', 'johndoe'); formData.append ( 'id', 123456); var xhr = new XMLHttpRequest (); xhr.open ( 'POST', '/ server', true); xhr.onload = function (e) {...}; xhr.send (formData); }По суті, ми просто динамічно створюємо елемент <form> і додаємо в неї поля <input> за допомогою методу append.
При цьому форму можна не створювати з нуля. Об'єкти FormData можна форматувати за допомогою існуючих на сторінці елементів HTMLFormElement. наприклад:
<Form id = "myform" name = "myform" action = "/ server"> <input type = "text" name = "username" value = "johndoe"> <input type = "number" name = "id" value = "123456"> <input type = "submit" onclick = "return sendForm (this.form);"> </ form> function sendForm (form) {var formData = new formData (form); formData.append ( 'secret_token', '1234567890'); // Append extra data before send. var xhr = new XMLHttpRequest (); xhr.open ( 'POST', form.action, true); xhr.onload = function (e) {...}; xhr.send (formData); return false; // Prevent page from submitting. }HTML-форма може містити файли (наприклад, <input type = "file">). Об'єкт FormData теж підтримує цю можливість. Досить просто прикріпити файли, і браузер виконає запит multipart / form-data при виклику методу send ().
function uploadFiles (url, files) {var formData = new FormData (); for (var i = 0, file; file = files [i]; ++ i) {formData.append (file.name, file); } Var xhr = new XMLHttpRequest (); xhr.open ( 'POST', url, true); xhr.onload = function (e) {...}; xhr.send (formData); // multipart / form-data} document.querySelector ( 'input [type = "file"]'). AddEventListener ( 'change', function (e) {uploadFiles ( '/ server', this.files);}, false );Відправлення файлу або об'єкта Blob: xhr.send (Blob)
За допомогою XHR також можна відправити файл або об'єкт Blob. Слід пам'ятати, що файли є об'єктами Blob, тому в наших прикладах між ними немає різниці.
У цьому прикладі ми створюємо новий текстовий файл за допомогою API BlobBuilder і відправляємо цей об'єкт Blob на сервер. Цей код також запускає обробник, який показує нам хід відправки файлу.
<Progress min = "0" max = "100" value = "0"> 0% complete </ progress> function upload (blobOrFile) {var xhr = new XMLHttpRequest (); xhr.open ( 'POST', '/ server', true); xhr.onload = function (e) {...}; // Listen to the upload progress. var progressBar = document.querySelector ( 'progress'); xhr.upload.onprogress = function (e) {if (e.lengthComputable) {progressBar.value = (e.loaded / e.total) * 100; progressBar.textContent = progressBar.value; // Fallback for unsupported browsers. }}; xhr.send (blobOrFile); } // Take care of vendor prefixes. BlobBuilder = window.MozBlobBuilder || window.WebKitBlobBuilder || window.BlobBuilder; var bb = new BlobBuilder (); bb.append ( 'hello world'); upload (bb.getBlob ( 'text / plain'));Відправка довільного набору байтів: xhr.send (ArrayBuffer)
В якості корисних даних XHR також можна відправляти об'єкти ArrayBuffer.
function sendArrayBuffer () {var xhr = new XMLHttpRequest (); xhr.open ( 'POST', '/ server', true); xhr.onload = function (e) {...}; var uInt8Array = new Uint8Array ([1, 2, 3]); xhr.send (uInt8Array.buffer); }Обмін ресурсами із запитом походження (Cross Origin Resource Sharing, або CORS)
За допомогою технології CORS веб-додатки можуть виконувати крос-доменні AJAX-запити до інших доменів. Зробити це дуже просто: достатньо, щоб сервер відправив необхідний заголовок відповіді.
Включення CORS-запитів
Припустимо, додаток знаходиться в домені example.com і потрібно отримати дані з домену www.example2.com. Як правило, при спробі відправити такий AJAX-запит він не виконується, а браузер видає помилку невідповідності походження. Завдяки технології CORS сайт www.example2.com може дозволити програмі з сайту example.com виконувати запити шляхом додавання одного заголовка.
Access-Control-Allow-Origin: http://example.comТема Access-Control-Allow-Origin можна додати як для одного сайту, так і для всього домену. Щоб увімкнути надсилання запитів з усіх доменів, додайте рядок такого виду:
Access-Control-Allow-Origin: *Фактично на всіх сторінках цього сайту (html5rocks.com) також використовується технологія CORS. Запустіть інструменти розробника, і у відповіді ви побачите заголовок Access-Control-Allow-Origin:
Тема Access-Control-Allow-Origin на сайті html5rocks.comДозволити крос-доменні запити нескладно, тому настійно рекомендується включати CORS для загальнодоступних даних.
Створення крос-доменного запиту
Якщо сервер-адресат підтримує CORS, крос-доменний запит нічим не відрізняється від звичайного запиту XMLHttpRequest. Наприклад, ось так маєте змогу надсилати запити з додатка на сервері example.com до сервера www.example2.com:
var xhr = new XMLHttpRequest (); xhr.open ( 'GET', 'http://www.example2.com/hello.json'); xhr.onload = function (e) {var data = JSON.parse (this.response); ...} xhr.send ();практичні приклади
Завантаження і збереження файлів в файлову систему HTML5
Припустимо, у вас є галерея зображень і ви хочете зберегти кілька картинок у себе за допомогою файлової системи HTML5 . Ви можете запросити ці картинки як об'єкти ArrayBuffer, створити на основі цих даних об'єкт Blob і записати його за допомогою FileWriter.
window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem; function onError (e) {console.log ( 'Error', e); } Var xhr = new XMLHttpRequest (); xhr.open ( 'GET', '/path/to/image.png', true); xhr.responseType = 'arraybuffer'; xhr.onload = function (e) {window.requestFileSystem (TEMPORARY, 1024 * 1024, function (fs) {fs.root.getFile ( 'image.png', {create: true}, function (fileEntry) {fileEntry.createWriter (function (writer) {writer.onwrite = function (e) {...}; writer.onerror = function (e) {...}; var bb = new BlobBuilder (); bb.append (xhr.response) ; writer.write (bb.getBlob ( 'image / png'));}, onError);}, onError);}, onError); }; xhr.send ();Зверніть увагу: для використання цього коду потрібно ознайомитися з умовами підтримки браузерів і обмеженнями на зберігання в керівництві Знайомство з API файлової системи .
Відправлення файлу по частинах
API файлів істотно полегшує відправку великих файлів. Методика така: великий файл розбивається на кілька дрібних, які потім відправляються за допомогою XHR і збираються назад на сервері. Приблизно так само Gmail швидко відправляє великі прикріплені файли. Ця технологія також дозволяє обійти обмеження Google App Engine: 32 МБ на один HTTP-запит.
window.BlobBuilder = window.MozBlobBuilder || window.WebKitBlobBuilder || window.BlobBuilder; function upload (blobOrFile) {var xhr = new XMLHttpRequest (); xhr.open ( 'POST', '/ server', true); xhr.onload = function (e) {...}; xhr.send (blobOrFile); } Document.querySelector ( 'input [type = "file"]'). AddEventListener ( 'change', function (e) {var blob = this.files [0]; const BYTES_PER_CHUNK = 1024 * 1024; // 1MB chunk sizes . const SIZE = blob.size; var start = 0; var end = BYTES_PER_CHUNK; while (start <SIZE) {// Note: blob.slice has changed semantics and been prefixed. See http://goo.gl/U9mE5. if ( 'mozSlice' in blob) {var chunk = blob.mozSlice (start, end);} else {var chunk = blob.webkitSlice (start, end);} upload (chunk); start = end; end = start + BYTES_PER_CHUNK;}}, false); }) ();Нижче наведено код для збірки файлу на сервері.
Перевірте, як він працює.
Корисні посилання
New Tricks in XMLHttpRequest2
Вступ
Одним з найважливіших елементів в середовищі HTML5 є XMLHttpRequest. Строго кажучи, цей об'єкт не входить в HTML5. Однак він став результатом постійних змін, що вносяться розробниками браузерів в базову платформу. XHR2 грає велику роль, так як є невід'ємною частиною сучасних складних веб-додатків.
Мало хто знає, що в останню версію XHR було додано багато функцій. В XMLHttpRequest Level 2 представлена маса нових можливостей, які позбавлять нас від непотрібних операцій і таких понять, як крос-доменні запити, події ходу відправки файлів, а також підтримка завантаження і відправки двійкових даних. Завдяки цьому технологія AJAX працює в поєднанні з новітніми API HTML5: API файлової системи , API веб-аудіо і WebGL.
У цьому посібнику описано деякі з нових можливостей XMLHttpRequest і особливо ті з них, які необхідні для роботи з файлами .
витяг даних
Завантаження файлу у вигляді довічного об'єкта за допомогою XHR завжди була проблемою. З технічної точки зору це було навіть неможливо. Один з відомих способів полягає в перевизначенні mime-типу користувальницької кодуванням, як показано нижче.
Раніше вміст картинки можна було витягти таким способом:
var xhr = new XMLHttpRequest (); xhr.open ( 'GET', '/path/to/image.png', true); // Hack to pass bytes through unprocessed. xhr.overrideMimeType ( 'text / plain; charset = x-user-defined'); xhr.onreadystatechange = function (e) {if (this.readyState == 4 && this.status == 200) {var binStr = this.responseText; for (var i = 0, len = binStr.length; i <len; ++ i) {var c = binStr.charCodeAt (i); //String.fromCharCode(c & 0xff); var byte = c & 0xff; // byte at offset i}}}; xhr.send ();Цей спосіб працює, проте елемент responseText зовсім не є великим двійковим об'єктом (елементом blob). Це двоичная рядок, що представляє файл картинки. Ми змушуємо сервер повернути дані в необробленому вигляді. Хоча цей прийом працює, я не рекомендую використовувати його. При спробі примусово перевести дані в потрібний формат за допомогою маніпуляцій з кодуванням і рядками завжди виникають проблеми.
Вказівка формату відповіді
У попередньому прикладі картинка завантажувалася у вигляді виконуваного файлу шляхом перевизначення mime-типу сервера і обробки тексту як двійковій рядки. Замість цього скористаємося новими можливостями технології XMLHttpRequest: властивостями responseType і response, що дозволяють вказати браузеру бажаний формат відповіді.
xhr. responseType Перш ніж відправити запит, необхідно задати для властивості xhr.responseType значення text, arraybuffer, blob або document. Зверніть увагу: якщо встановити значення xhr.responseType = '' або опустити його, за замовчуванням вибирається формат text. xhr. response Після успішного виконання запиту властивість response буде містити запитані дані в форматі DOMString, ArrayBuffer, Blob або Document відповідно до значення responseType.Переробимо попередній приклад з використанням цієї нової можливості. Тепер ми витягуємо дані картинки в форматі ArrayBuffer замість рядка. Передаємо буфер в API BlobBuilder і отримуємо об'єкт Blob.
BlobBuilder = window.MozBlobBuilder || window.WebKitBlobBuilder || window.BlobBuilder; var xhr = new XMLHttpRequest (); xhr.open ( 'GET', '/path/to/image.png', true); xhr.responseType = 'arraybuffer'; xhr.onload = function (e) {if (this.status == 200) {var bb = new BlobBuilder (); bb.append (this.response); // Note: not xhr.responseText var blob = bb.getBlob ( 'image / png'); ...}}; xhr.send ();Так набагато краще.
Відповіді в форматі ArrayBuffer
ArrayBuffer - це стандартний контейнер фіксованої довжини для двійкових даних. Це дуже зручний універсальний буфер для необробленої інформації, але його головна перевага - можливість створювати "вистави" вихідних даних за допомогою типізованих масивів JavaScript . Фактично на базі одного джерела ArrayBuffer можна сформувати кілька подань. Наприклад, можна створити 8-бітний цілочисельний масив, який використовує той же об'єкт ArrayBuffer, що і 32-бітний масив на базі тих же даних. Вихідна інформація залишається незмінною: вона просто видається в різному вигляді.
У прикладі нижче ми витягуємо ту ж картинку у форматі ArrayBuffer, але на цей раз створюємо з даних в буфері 8-бітний цілочисельний масив.
var xhr = new XMLHttpRequest (); xhr.open ( 'GET', '/path/to/image.png', true); xhr.responseType = 'arraybuffer'; xhr.onload = function (e) {var uInt8Array = new Uint8Array (this.response); // this.response == uInt8Array.buffer // var byte3 = uInt8Array [4]; // byte at offset 4 ...}; xhr.send ();Відповіді в форматі Blob
Для безпосередньої роботи з об'єктами Blob без операцій з окремими байтами файлу можна використовувати значення xhr.responseType = 'blob'.
window.URL = window.URL || window.webkitURL; // Take care of vendor prefixes. var xhr = new XMLHttpRequest (); xhr.open ( 'GET', '/path/to/image.png', true); xhr.responseType = 'blob'; xhr.onload = function (e) {if (this.status == 200) {var blob = this.response; var img = document.createElement ( 'img'); img.onload = function (e) {window.URL.revokeObjectURL (img.src); // Clean up after yourself. }; img.src = window.URL.createObjectURL (blob); document.body.appendChild (img); ...}}; xhr.send ();Об'єкт Blob можна використовувати по різному: наприклад, зберегти його в індексованої базі даних , Записати в файлову систему HTML5 або створити URL елемента Blob , Як показано в цьому прикладі.
Відправка даних
можливість завантажувати дані в різних форматах дуже важлива, але вона абсолютно непотрібна, якщо ці дані не можна відправити назад (на сервер). До недавнього часу в XMLHttpRequest можна було відправляти тільки дані DOMString або Document (XML). Ситуація змінилася. Перероблений метод send () дозволяє відправляти дані будь-яких типів: DOMString, Document, FormData, Blob, File і ArrayBuffer. Приклади в цій частині розділу ілюструють відправку даних кожного з цих типів.
Відправка строкових даних: xhr.send (DOMString)
function sendText (txt) {var xhr = new XMLHttpRequest (); xhr.open ( 'POST', '/ server', true); xhr.onload = function (e) {if (this.status == 200) {console.log (this.responseText); }}; xhr.send (txt); } SendText ( 'test string'); function sendTextNew (txt) {var xhr = new XMLHttpRequest (); xhr.open ( 'POST', '/ server', true); xhr.responseType = 'text'; xhr.onload = function (e) {if (this.status == 200) {console.log (this.response); }}; xhr.send (txt); } SendText2 ( 'test string');Як бачите, нічого нового. Хоча права частина дещо відрізняється. У ній є рядок responseType = 'text'. Втім, її відсутність не змінює результат.
Багато з нас звикли користуватися плагінами jQuery і іншими бібліотеками для відправки форм AJAX. Замість них можна використовувати FormData - ще один новий тип даних в рамках технології XHR2. Тип FormData дуже зручний для динамічного створення HTML-елементів <form> за допомогою JavaScript. Потім ці форми можна відправити за допомогою AJAX.
function sendForm () {var formData = new FormData (); formData.append ( 'username', 'johndoe'); formData.append ( 'id', 123456); var xhr = new XMLHttpRequest (); xhr.open ( 'POST', '/ server', true); xhr.onload = function (e) {...}; xhr.send (formData); }По суті, ми просто динамічно створюємо елемент <form> і додаємо в неї поля <input> за допомогою методу append.
При цьому форму можна не створювати з нуля. Об'єкти FormData можна форматувати за допомогою існуючих на сторінці елементів HTMLFormElement. наприклад:
<Form id = "myform" name = "myform" action = "/ server"> <input type = "text" name = "username" value = "johndoe"> <input type = "number" name = "id" value = "123456"> <input type = "submit" onclick = "return sendForm (this.form);"> </ form> function sendForm (form) {var formData = new formData (form); formData.append ( 'secret_token', '1234567890'); // Append extra data before send. var xhr = new XMLHttpRequest (); xhr.open ( 'POST', form.action, true); xhr.onload = function (e) {...}; xhr.send (formData); return false; // Prevent page from submitting. }HTML-форма може містити файли (наприклад, <input type = "file">). Об'єкт FormData теж підтримує цю можливість. Досить просто прикріпити файли, і браузер виконає запит multipart / form-data при виклику методу send ().
function uploadFiles (url, files) {var formData = new FormData (); for (var i = 0, file; file = files [i]; ++ i) {formData.append (file.name, file); } Var xhr = new XMLHttpRequest (); xhr.open ( 'POST', url, true); xhr.onload = function (e) {...}; xhr.send (formData); // multipart / form-data} document.querySelector ( 'input [type = "file"]'). AddEventListener ( 'change', function (e) {uploadFiles ( '/ server', this.files);}, false );Відправлення файлу або об'єкта Blob: xhr.send (Blob)
За допомогою XHR також можна відправити файл або об'єкт Blob. Слід пам'ятати, що файли є об'єктами Blob, тому в наших прикладах між ними немає різниці.
У цьому прикладі ми створюємо новий текстовий файл за допомогою API BlobBuilder і відправляємо цей об'єкт Blob на сервер. Цей код також запускає обробник, який показує нам хід відправки файлу.
<Progress min = "0" max = "100" value = "0"> 0% complete </ progress> function upload (blobOrFile) {var xhr = new XMLHttpRequest (); xhr.open ( 'POST', '/ server', true); xhr.onload = function (e) {...}; // Listen to the upload progress. var progressBar = document.querySelector ( 'progress'); xhr.upload.onprogress = function (e) {if (e.lengthComputable) {progressBar.value = (e.loaded / e.total) * 100; progressBar.textContent = progressBar.value; // Fallback for unsupported browsers. }}; xhr.send (blobOrFile); } // Take care of vendor prefixes. BlobBuilder = window.MozBlobBuilder || window.WebKitBlobBuilder || window.BlobBuilder; var bb = new BlobBuilder (); bb.append ( 'hello world'); upload (bb.getBlob ( 'text / plain'));Відправка довільного набору байтів: xhr.send (ArrayBuffer)
В якості корисних даних XHR також можна відправляти об'єкти ArrayBuffer.
function sendArrayBuffer () {var xhr = new XMLHttpRequest (); xhr.open ( 'POST', '/ server', true); xhr.onload = function (e) {...}; var uInt8Array = new Uint8Array ([1, 2, 3]); xhr.send (uInt8Array.buffer); }Обмін ресурсами із запитом походження (Cross Origin Resource Sharing, або CORS)
За допомогою технології CORS веб-додатки можуть виконувати крос-доменні AJAX-запити до інших доменів. Зробити це дуже просто: достатньо, щоб сервер відправив необхідний заголовок відповіді.
Включення CORS-запитів
Припустимо, додаток знаходиться в домені example.com і потрібно отримати дані з домену www.example2.com. Як правило, при спробі відправити такий AJAX-запит він не виконується, а браузер видає помилку невідповідності походження. Завдяки технології CORS сайт www.example2.com може дозволити програмі з сайту example.com виконувати запити шляхом додавання одного заголовка.
Access-Control-Allow-Origin: http://example.comТема Access-Control-Allow-Origin можна додати як для одного сайту, так і для всього домену. Щоб увімкнути надсилання запитів з усіх доменів, додайте рядок такого виду:
Access-Control-Allow-Origin: *Фактично на всіх сторінках цього сайту (html5rocks.com) також використовується технологія CORS. Запустіть інструменти розробника, і у відповіді ви побачите заголовок Access-Control-Allow-Origin:
Тема Access-Control-Allow-Origin на сайті html5rocks.comДозволити крос-доменні запити нескладно, тому настійно рекомендується включати CORS для загальнодоступних даних.
Створення крос-доменного запиту
Якщо сервер-адресат підтримує CORS, крос-доменний запит нічим не відрізняється від звичайного запиту XMLHttpRequest. Наприклад, ось так маєте змогу надсилати запити з додатка на сервері example.com до сервера www.example2.com:
var xhr = new XMLHttpRequest (); xhr.open ( 'GET', 'http://www.example2.com/hello.json'); xhr.onload = function (e) {var data = JSON.parse (this.response); ...} xhr.send ();практичні приклади
Завантаження і збереження файлів в файлову систему HTML5
Припустимо, у вас є галерея зображень і ви хочете зберегти кілька картинок у себе за допомогою файлової системи HTML5 . Ви можете запросити ці картинки як об'єкти ArrayBuffer, створити на основі цих даних об'єкт Blob і записати його за допомогою FileWriter.
window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem; function onError (e) {console.log ( 'Error', e); } Var xhr = new XMLHttpRequest (); xhr.open ( 'GET', '/path/to/image.png', true); xhr.responseType = 'arraybuffer'; xhr.onload = function (e) {window.requestFileSystem (TEMPORARY, 1024 * 1024, function (fs) {fs.root.getFile ( 'image.png', {create: true}, function (fileEntry) {fileEntry.createWriter (function (writer) {writer.onwrite = function (e) {...}; writer.onerror = function (e) {...}; var bb = new BlobBuilder (); bb.append (xhr.response) ; writer.write (bb.getBlob ( 'image / png'));}, onError);}, onError);}, onError); }; xhr.send ();Зверніть увагу: для використання цього коду потрібно ознайомитися з умовами підтримки браузерів і обмеженнями на зберігання в керівництві Знайомство з API файлової системи .
Відправлення файлу по частинах
API файлів істотно полегшує відправку великих файлів. Методика така: великий файл розбивається на кілька дрібних, які потім відправляються за допомогою XHR і збираються назад на сервері. Приблизно так само Gmail швидко відправляє великі прикріплені файли. Ця технологія також дозволяє обійти обмеження Google App Engine: 32 МБ на один HTTP-запит.
window.BlobBuilder = window.MozBlobBuilder || window.WebKitBlobBuilder || window.BlobBuilder; function upload (blobOrFile) {var xhr = new XMLHttpRequest (); xhr.open ( 'POST', '/ server', true); xhr.onload = function (e) {...}; xhr.send (blobOrFile); } Document.querySelector ( 'input [type = "file"]'). AddEventListener ( 'change', function (e) {var blob = this.files [0]; const BYTES_PER_CHUNK = 1024 * 1024; // 1MB chunk sizes . const SIZE = blob.size; var start = 0; var end = BYTES_PER_CHUNK; while (start <SIZE) {// Note: blob.slice has changed semantics and been prefixed. See http://goo.gl/U9mE5. if ( 'mozSlice' in blob) {var chunk = blob.mozSlice (start, end);} else {var chunk = blob.webkitSlice (start, end);} upload (chunk); start = end; end = start + BYTES_PER_CHUNK;}}, false); }) ();Нижче наведено код для збірки файлу на сервері.
Перевірте, як він працює.
Корисні посилання
New Tricks in XMLHttpRequest2
Вступ
Одним з найважливіших елементів в середовищі HTML5 є XMLHttpRequest. Строго кажучи, цей об'єкт не входить в HTML5. Однак він став результатом постійних змін, що вносяться розробниками браузерів в базову платформу. XHR2 грає велику роль, так як є невід'ємною частиною сучасних складних веб-додатків.
Мало хто знає, що в останню версію XHR було додано багато функцій. В XMLHttpRequest Level 2 представлена маса нових можливостей, які позбавлять нас від непотрібних операцій і таких понять, як крос-доменні запити, події ходу відправки файлів, а також підтримка завантаження і відправки двійкових даних. Завдяки цьому технологія AJAX працює в поєднанні з новітніми API HTML5: API файлової системи , API веб-аудіо і WebGL.
У цьому посібнику описано деякі з нових можливостей XMLHttpRequest і особливо ті з них, які необхідні для роботи з файлами .
витяг даних
Завантаження файлу у вигляді довічного об'єкта за допомогою XHR завжди була проблемою. З технічної точки зору це було навіть неможливо. Один з відомих способів полягає в перевизначенні mime-типу користувальницької кодуванням, як показано нижче.
Раніше вміст картинки можна було витягти таким способом:
var xhr = new XMLHttpRequest (); xhr.open ( 'GET', '/path/to/image.png', true); // Hack to pass bytes through unprocessed. xhr.overrideMimeType ( 'text / plain; charset = x-user-defined'); xhr.onreadystatechange = function (e) {if (this.readyState == 4 && this.status == 200) {var binStr = this.responseText; for (var i = 0, len = binStr.length; i <len; ++ i) {var c = binStr.charCodeAt (i); //String.fromCharCode(c & 0xff); var byte = c & 0xff; // byte at offset i}}}; xhr.send ();Цей спосіб працює, проте елемент responseText зовсім не є великим двійковим об'єктом (елементом blob). Це двоичная рядок, що представляє файл картинки. Ми змушуємо сервер повернути дані в необробленому вигляді. Хоча цей прийом працює, я не рекомендую використовувати його. При спробі примусово перевести дані в потрібний формат за допомогою маніпуляцій з кодуванням і рядками завжди виникають проблеми.
Вказівка формату відповіді
У попередньому прикладі картинка завантажувалася у вигляді виконуваного файлу шляхом перевизначення mime-типу сервера і обробки тексту як двійковій рядки. Замість цього скористаємося новими можливостями технології XMLHttpRequest: властивостями responseType і response, що дозволяють вказати браузеру бажаний формат відповіді.
xhr. responseType Перш ніж відправити запит, необхідно задати для властивості xhr.responseType значення text, arraybuffer, blob або document. Зверніть увагу: якщо встановити значення xhr.responseType = '' або опустити його, за замовчуванням вибирається формат text. xhr. response Після успішного виконання запиту властивість response буде містити запитані дані в форматі DOMString, ArrayBuffer, Blob або Document відповідно до значення responseType.Переробимо попередній приклад з використанням цієї нової можливості. Тепер ми витягуємо дані картинки в форматі ArrayBuffer замість рядка. Передаємо буфер в API BlobBuilder і отримуємо об'єкт Blob.
BlobBuilder = window.MozBlobBuilder || window.WebKitBlobBuilder || window.BlobBuilder; var xhr = new XMLHttpRequest (); xhr.open ( 'GET', '/path/to/image.png', true); xhr.responseType = 'arraybuffer'; xhr.onload = function (e) {if (this.status == 200) {var bb = new BlobBuilder (); bb.append (this.response); // Note: not xhr.responseText var blob = bb.getBlob ( 'image / png'); ...}}; xhr.send ();Так набагато краще.
Відповіді в форматі ArrayBuffer
ArrayBuffer - це стандартний контейнер фіксованої довжини для двійкових даних. Це дуже зручний універсальний буфер для необробленої інформації, але його головна перевага - можливість створювати "вистави" вихідних даних за допомогою типізованих масивів JavaScript . Фактично на базі одного джерела ArrayBuffer можна сформувати кілька подань. Наприклад, можна створити 8-бітний цілочисельний масив, який використовує той же об'єкт ArrayBuffer, що і 32-бітний масив на базі тих же даних. Вихідна інформація залишається незмінною: вона просто видається в різному вигляді.
У прикладі нижче ми витягуємо ту ж картинку у форматі ArrayBuffer, але на цей раз створюємо з даних в буфері 8-бітний цілочисельний масив.
var xhr = new XMLHttpRequest (); xhr.open ( 'GET', '/path/to/image.png', true); xhr.responseType = 'arraybuffer'; xhr.onload = function (e) {var uInt8Array = new Uint8Array (this.response); // this.response == uInt8Array.buffer // var byte3 = uInt8Array [4]; // byte at offset 4 ...}; xhr.send ();Відповіді в форматі Blob
Для безпосередньої роботи з об'єктами Blob без операцій з окремими байтами файлу можна використовувати значення xhr.responseType = 'blob'.
window.URL = window.URL || window.webkitURL; // Take care of vendor prefixes. var xhr = new XMLHttpRequest (); xhr.open ( 'GET', '/path/to/image.png', true); xhr.responseType = 'blob'; xhr.onload = function (e) {if (this.status == 200) {var blob = this.response; var img = document.createElement ( 'img'); img.onload = function (e) {window.URL.revokeObjectURL (img.src); // Clean up after yourself. }; img.src = window.URL.createObjectURL (blob); document.body.appendChild (img); ...}}; xhr.send ();Об'єкт Blob можна використовувати по різному: наприклад, зберегти його в індексованої базі даних , Записати в файлову систему HTML5 або створити URL елемента Blob , Як показано в цьому прикладі.
Відправка даних
можливість завантажувати дані в різних форматах дуже важлива, але вона абсолютно непотрібна, якщо ці дані не можна відправити назад (на сервер). До недавнього часу в XMLHttpRequest можна було відправляти тільки дані DOMString або Document (XML). Ситуація змінилася. Перероблений метод send () дозволяє відправляти дані будь-яких типів: DOMString, Document, FormData, Blob, File і ArrayBuffer. Приклади в цій частині розділу ілюструють відправку даних кожного з цих типів.
Відправка строкових даних: xhr.send (DOMString)
function sendText (txt) {var xhr = new XMLHttpRequest (); xhr.open ( 'POST', '/ server', true); xhr.onload = function (e) {if (this.status == 200) {console.log (this.responseText); }}; xhr.send (txt); } SendText ( 'test string'); function sendTextNew (txt) {var xhr = new XMLHttpRequest (); xhr.open ( 'POST', '/ server', true); xhr.responseType = 'text'; xhr.onload = function (e) {if (this.status == 200) {console.log (this.response); }}; xhr.send (txt); } SendText2 ( 'test string');Як бачите, нічого нового. Хоча права частина дещо відрізняється. У ній є рядок responseType = 'text'. Втім, її відсутність не змінює результат.
Багато з нас звикли користуватися плагінами jQuery і іншими бібліотеками для відправки форм AJAX. Замість них можна використовувати FormData - ще один новий тип даних в рамках технології XHR2. Тип FormData дуже зручний для динамічного створення HTML-елементів <form> за допомогою JavaScript. Потім ці форми можна відправити за допомогою AJAX.
function sendForm () {var formData = new FormData (); formData.append ( 'username', 'johndoe'); formData.append ( 'id', 123456); var xhr = new XMLHttpRequest (); xhr.open ( 'POST', '/ server', true); xhr.onload = function (e) {...}; xhr.send (formData); }По суті, ми просто динамічно створюємо елемент <form> і додаємо в неї поля <input> за допомогою методу append.
При цьому форму можна не створювати з нуля. Об'єкти FormData можна форматувати за допомогою існуючих на сторінці елементів HTMLFormElement. наприклад:
<Form id = "myform" name = "myform" action = "/ server"> <input type = "text" name = "username" value = "johndoe"> <input type = "number" name = "id" value = "123456"> <input type = "submit" onclick = "return sendForm (this.form);"> </ form> function sendForm (form) {var formData = new formData (form); formData.append ( 'secret_token', '1234567890'); // Append extra data before send. var xhr = new XMLHttpRequest (); xhr.open ( 'POST', form.action, true); xhr.onload = function (e) {...}; xhr.send (formData); return false; // Prevent page from submitting. }HTML-форма може містити файли (наприклад, <input type = "file">). Об'єкт FormData теж підтримує цю можливість. Досить просто прикріпити файли, і браузер виконає запит multipart / form-data при виклику методу send ().
function uploadFiles (url, files) {var formData = new FormData (); for (var i = 0, file; file = files [i]; ++ i) {formData.append (file.name, file); } Var xhr = new XMLHttpRequest (); xhr.open ( 'POST', url, true); xhr.onload = function (e) {...}; xhr.send (formData); // multipart / form-data} document.querySelector ( 'input [type = "file"]'). AddEventListener ( 'change', function (e) {uploadFiles ( '/ server', this.files);}, false );Відправлення файлу або об'єкта Blob: xhr.send (Blob)
За допомогою XHR також можна відправити файл або об'єкт Blob. Слід пам'ятати, що файли є об'єктами Blob, тому в наших прикладах між ними немає різниці.
У цьому прикладі ми створюємо новий текстовий файл за допомогою API BlobBuilder і відправляємо цей об'єкт Blob на сервер. Цей код також запускає обробник, який показує нам хід відправки файлу.
<Progress min = "0" max = "100" value = "0"> 0% complete </ progress> function upload (blobOrFile) {var xhr = new XMLHttpRequest (); xhr.open ( 'POST', '/ server', true); xhr.onload = function (e) {...}; // Listen to the upload progress. var progressBar = document.querySelector ( 'progress'); xhr.upload.onprogress = function (e) {if (e.lengthComputable) {progressBar.value = (e.loaded / e.total) * 100; progressBar.textContent = progressBar.value; // Fallback for unsupported browsers. }}; xhr.send (blobOrFile); } // Take care of vendor prefixes. BlobBuilder = window.MozBlobBuilder || window.WebKitBlobBuilder || window.BlobBuilder; var bb = new BlobBuilder (); bb.append ( 'hello world'); upload (bb.getBlob ( 'text / plain'));Відправка довільного набору байтів: xhr.send (ArrayBuffer)
В якості корисних даних XHR також можна відправляти об'єкти ArrayBuffer.
function sendArrayBuffer () {var xhr = new XMLHttpRequest (); xhr.open ( 'POST', '/ server', true); xhr.onload = function (e) {...}; var uInt8Array = new Uint8Array ([1, 2, 3]); xhr.send (uInt8Array.buffer); }Обмін ресурсами із запитом походження (Cross Origin Resource Sharing, або CORS)
За допомогою технології CORS веб-додатки можуть виконувати крос-доменні AJAX-запити до інших доменів. Зробити це дуже просто: достатньо, щоб сервер відправив необхідний заголовок відповіді.
Включення CORS-запитів
Припустимо, додаток знаходиться в домені example.com і потрібно отримати дані з домену www.example2.com. Як правило, при спробі відправити такий AJAX-запит він не виконується, а браузер видає помилку невідповідності походження. Завдяки технології CORS сайт www.example2.com може дозволити програмі з сайту example.com виконувати запити шляхом додавання одного заголовка.
Access-Control-Allow-Origin: http://example.comТема Access-Control-Allow-Origin можна додати як для одного сайту, так і для всього домену. Щоб увімкнути надсилання запитів з усіх доменів, додайте рядок такого виду:
Access-Control-Allow-Origin: *Фактично на всіх сторінках цього сайту (html5rocks.com) також використовується технологія CORS. Запустіть інструменти розробника, і у відповіді ви побачите заголовок Access-Control-Allow-Origin:
Тема Access-Control-Allow-Origin на сайті html5rocks.comДозволити крос-доменні запити нескладно, тому настійно рекомендується включати CORS для загальнодоступних даних.
Створення крос-доменного запиту
Якщо сервер-адресат підтримує CORS, крос-доменний запит нічим не відрізняється від звичайного запиту XMLHttpRequest. Наприклад, ось так маєте змогу надсилати запити з додатка на сервері example.com до сервера www.example2.com:
var xhr = new XMLHttpRequest (); xhr.open ( 'GET', 'http://www.example2.com/hello.json'); xhr.onload = function (e) {var data = JSON.parse (this.response); ...} xhr.send ();практичні приклади
Завантаження і збереження файлів в файлову систему HTML5
Припустимо, у вас є галерея зображень і ви хочете зберегти кілька картинок у себе за допомогою файлової системи HTML5 . Ви можете запросити ці картинки як об'єкти ArrayBuffer, створити на основі цих даних об'єкт Blob і записати його за допомогою FileWriter.
window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem; function onError (e) {console.log ( 'Error', e); } Var xhr = new XMLHttpRequest (); xhr.open ( 'GET', '/path/to/image.png', true); xhr.responseType = 'arraybuffer'; xhr.onload = function (e) {window.requestFileSystem (TEMPORARY, 1024 * 1024, function (fs) {fs.root.getFile ( 'image.png', {create: true}, function (fileEntry) {fileEntry.createWriter (function (writer) {writer.onwrite = function (e) {...}; writer.onerror = function (e) {...}; var bb = new BlobBuilder (); bb.append (xhr.response) ; writer.write (bb.getBlob ( 'image / png'));}, onError);}, onError);}, onError); }; xhr.send ();Зверніть увагу: для використання цього коду потрібно ознайомитися з умовами підтримки браузерів і обмеженнями на зберігання в керівництві Знайомство з API файлової системи .
Відправлення файлу по частинах
API файлів істотно полегшує відправку великих файлів. Методика така: великий файл розбивається на кілька дрібних, які потім відправляються за допомогою XHR і збираються назад на сервері. Приблизно так само Gmail швидко відправляє великі прикріплені файли. Ця технологія також дозволяє обійти обмеження Google App Engine: 32 МБ на один HTTP-запит.
window.BlobBuilder = window.MozBlobBuilder || window.WebKitBlobBuilder || window.BlobBuilder; function upload (blobOrFile) {var xhr = new XMLHttpRequest (); xhr.open ( 'POST', '/ server', true); xhr.onload = function (e) {...}; xhr.send (blobOrFile); } Document.querySelector ( 'input [type = "file"]'). AddEventListener ( 'change', function (e) {var blob = this.files [0]; const BYTES_PER_CHUNK = 1024 * 1024; // 1MB chunk sizes . const SIZE = blob.size; var start = 0; var end = BYTES_PER_CHUNK; while (start <SIZE) {// Note: blob.slice has changed semantics and been prefixed. See http://goo.gl/U9mE5. if ( 'mozSlice' in blob) {var chunk = blob.mozSlice (start, end);} else {var chunk = blob.webkitSlice (start, end);} upload (chunk); start = end; end = start + BYTES_PER_CHUNK;}}, false); }) ();Нижче наведено код для збірки файлу на сервері.
Перевірте, як він працює.
Корисні посилання
New Tricks in XMLHttpRequest2
Вступ
Одним з найважливіших елементів в середовищі HTML5 є XMLHttpRequest. Строго кажучи, цей об'єкт не входить в HTML5. Однак він став результатом постійних змін, що вносяться розробниками браузерів в базову платформу. XHR2 грає велику роль, так як є невід'ємною частиною сучасних складних веб-додатків.
Мало хто знає, що в останню версію XHR було додано багато функцій. В XMLHttpRequest Level 2 представлена маса нових можливостей, які позбавлять нас від непотрібних операцій і таких понять, як крос-доменні запити, події ходу відправки файлів, а також підтримка завантаження і відправки двійкових даних. Завдяки цьому технологія AJAX працює в поєднанні з новітніми API HTML5: API файлової системи , API веб-аудіо і WebGL.
У цьому посібнику описано деякі з нових можливостей XMLHttpRequest і особливо ті з них, які необхідні для роботи з файлами .
витяг даних
Завантаження файлу у вигляді довічного об'єкта за допомогою XHR завжди була проблемою. З технічної точки зору це було навіть неможливо. Один з відомих способів полягає в перевизначенні mime-типу користувальницької кодуванням, як показано нижче.
Раніше вміст картинки можна було витягти таким способом:
var xhr = new XMLHttpRequest (); xhr.open ( 'GET', '/path/to/image.png', true); // Hack to pass bytes through unprocessed. xhr.overrideMimeType ( 'text / plain; charset = x-user-defined'); xhr.onreadystatechange = function (e) {if (this.readyState == 4 && this.status == 200) {var binStr = this.responseText; for (var i = 0, len = binStr.length; i <len; ++ i) {var c = binStr.charCodeAt (i); //String.fromCharCode(c & 0xff); var byte = c & 0xff; // byte at offset i}}}; xhr.send ();Цей спосіб працює, проте елемент responseText зовсім не є великим двійковим об'єктом (елементом blob). Це двоичная рядок, що представляє файл картинки. Ми змушуємо сервер повернути дані в необробленому вигляді. Хоча цей прийом працює, я не рекомендую використовувати його. При спробі примусово перевести дані в потрібний формат за допомогою маніпуляцій з кодуванням і рядками завжди виникають проблеми.
Вказівка формату відповіді
У попередньому прикладі картинка завантажувалася у вигляді виконуваного файлу шляхом перевизначення mime-типу сервера і обробки тексту як двійковій рядки. Замість цього скористаємося новими можливостями технології XMLHttpRequest: властивостями responseType і response, що дозволяють вказати браузеру бажаний формат відповіді.
xhr. responseType Перш ніж відправити запит, необхідно задати для властивості xhr.responseType значення text, arraybuffer, blob або document. Зверніть увагу: якщо встановити значення xhr.responseType = '' або опустити його, за замовчуванням вибирається формат text. xhr. response Після успішного виконання запиту властивість response буде містити запитані дані в форматі DOMString, ArrayBuffer, Blob або Document відповідно до значення responseType.Переробимо попередній приклад з використанням цієї нової можливості. Тепер ми витягуємо дані картинки в форматі ArrayBuffer замість рядка. Передаємо буфер в API BlobBuilder і отримуємо об'єкт Blob.
BlobBuilder = window.MozBlobBuilder || window.WebKitBlobBuilder || window.BlobBuilder; var xhr = new XMLHttpRequest (); xhr.open ( 'GET', '/path/to/image.png', true); xhr.responseType = 'arraybuffer'; xhr.onload = function (e) {if (this.status == 200) {var bb = new BlobBuilder (); bb.append (this.response); // Note: not xhr.responseText var blob = bb.getBlob ( 'image / png'); ...}}; xhr.send ();Так набагато краще.
Відповіді в форматі ArrayBuffer
ArrayBuffer - це стандартний контейнер фіксованої довжини для двійкових даних. Це дуже зручний універсальний буфер для необробленої інформації, але його головна перевага - можливість створювати "вистави" вихідних даних за допомогою типізованих масивів JavaScript . Фактично на базі одного джерела ArrayBuffer можна сформувати кілька подань. Наприклад, можна створити 8-бітний цілочисельний масив, який використовує той же об'єкт ArrayBuffer, що і 32-бітний масив на базі тих же даних. Вихідна інформація залишається незмінною: вона просто видається в різному вигляді.
У прикладі нижче ми витягуємо ту ж картинку у форматі ArrayBuffer, але на цей раз створюємо з даних в буфері 8-бітний цілочисельний масив.
var xhr = new XMLHttpRequest (); xhr.open ( 'GET', '/path/to/image.png', true); xhr.responseType = 'arraybuffer'; xhr.onload = function (e) {var uInt8Array = new Uint8Array (this.response); // this.response == uInt8Array.buffer // var byte3 = uInt8Array [4]; // byte at offset 4 ...}; xhr.send ();Відповіді в форматі Blob
Для безпосередньої роботи з об'єктами Blob без операцій з окремими байтами файлу можна використовувати значення xhr.responseType = 'blob'.
window.URL = window.URL || window.webkitURL; // Take care of vendor prefixes. var xhr = new XMLHttpRequest (); xhr.open ( 'GET', '/path/to/image.png', true); xhr.responseType = 'blob'; xhr.onload = function (e) {if (this.status == 200) {var blob = this.response; var img = document.createElement ( 'img'); img.onload = function (e) {window.URL.revokeObjectURL (img.src); // Clean up after yourself. }; img.src = window.URL.createObjectURL (blob); document.body.appendChild (img); ...}}; xhr.send ();Об'єкт Blob можна використовувати по різному: наприклад, зберегти його в індексованої базі даних , Записати в файлову систему HTML5 або створити URL елемента Blob , Як показано в цьому прикладі.
Відправка даних
можливість завантажувати дані в різних форматах дуже важлива, але вона абсолютно непотрібна, якщо ці дані не можна відправити назад (на сервер). До недавнього часу в XMLHttpRequest можна було відправляти тільки дані DOMString або Document (XML). Ситуація змінилася. Перероблений метод send () дозволяє відправляти дані будь-яких типів: DOMString, Document, FormData, Blob, File і ArrayBuffer. Приклади в цій частині розділу ілюструють відправку даних кожного з цих типів.
Відправка строкових даних: xhr.send (DOMString)
function sendText (txt) {var xhr = new XMLHttpRequest (); xhr.open ( 'POST', '/ server', true); xhr.onload = function (e) {if (this.status == 200) {console.log (this.responseText); }}; xhr.send (txt); } SendText ( 'test string'); function sendTextNew (txt) {var xhr = new XMLHttpRequest (); xhr.open ( 'POST', '/ server', true); xhr.responseType = 'text'; xhr.onload = function (e) {if (this.status == 200) {console.log (this.response); }}; xhr.send (txt); } SendText2 ( 'test string');Як бачите, нічого нового. Хоча права частина дещо відрізняється. У ній є рядок responseType = 'text'. Втім, її відсутність не змінює результат.
Багато з нас звикли користуватися плагінами jQuery і іншими бібліотеками для відправки форм AJAX. Замість них можна використовувати FormData - ще один новий тип даних в рамках технології XHR2. Тип FormData дуже зручний для динамічного створення HTML-елементів <form> за допомогою JavaScript. Потім ці форми можна відправити за допомогою AJAX.
function sendForm () {var formData = new FormData (); formData.append ( 'username', 'johndoe'); formData.append ( 'id', 123456); var xhr = new XMLHttpRequest (); xhr.open ( 'POST', '/ server', true); xhr.onload = function (e) {...}; xhr.send (formData); }По суті, ми просто динамічно створюємо елемент <form> і додаємо в неї поля <input> за допомогою методу append.
При цьому форму можна не створювати з нуля. Об'єкти FormData можна форматувати за допомогою існуючих на сторінці елементів HTMLFormElement. наприклад:
<Form id = "myform" name = "myform" action = "/ server"> <input type = "text" name = "username" value = "johndoe"> <input type = "number" name = "id" value = "123456"> <input type = "submit" onclick = "return sendForm (this.form);"> </ form> function sendForm (form) {var formData = new formData (form); formData.append ( 'secret_token', '1234567890'); // Append extra data before send. var xhr = new XMLHttpRequest (); xhr.open ( 'POST', form.action, true); xhr.onload = function (e) {...}; xhr.send (formData); return false; // Prevent page from submitting. }HTML-форма може містити файли (наприклад, <input type = "file">). Об'єкт FormData теж підтримує цю можливість. Досить просто прикріпити файли, і браузер виконає запит multipart / form-data при виклику методу send ().
function uploadFiles (url, files) {var formData = new FormData (); for (var i = 0, file; file = files [i]; ++ i) {formData.append (file.name, file); } Var xhr = new XMLHttpRequest (); xhr.open ( 'POST', url, true); xhr.onload = function (e) {...}; xhr.send (formData); // multipart / form-data} document.querySelector ( 'input [type = "file"]'). AddEventListener ( 'change', function (e) {uploadFiles ( '/ server', this.files);}, false );Відправлення файлу або об'єкта Blob: xhr.send (Blob)
За допомогою XHR також можна відправити файл або об'єкт Blob. Слід пам'ятати, що файли є об'єктами Blob, тому в наших прикладах між ними немає різниці.
У цьому прикладі ми створюємо новий текстовий файл за допомогою API BlobBuilder і відправляємо цей об'єкт Blob на сервер. Цей код також запускає обробник, який показує нам хід відправки файлу.
<Progress min = "0" max = "100" value = "0"> 0% complete </ progress> function upload (blobOrFile) {var xhr = new XMLHttpRequest (); xhr.open ( 'POST', '/ server', true); xhr.onload = function (e) {...}; // Listen to the upload progress. var progressBar = document.querySelector ( 'progress'); xhr.upload.onprogress = function (e) {if (e.lengthComputable) {progressBar.value = (e.loaded / e.total) * 100; progressBar.textContent = progressBar.value; // Fallback for unsupported browsers. }}; xhr.send (blobOrFile); } // Take care of vendor prefixes. BlobBuilder = window.MozBlobBuilder || window.WebKitBlobBuilder || window.BlobBuilder; var bb = new BlobBuilder (); bb.append ( 'hello world'); upload (bb.getBlob ( 'text / plain'));Відправка довільного набору байтів: xhr.send (ArrayBuffer)
В якості корисних даних XHR також можна відправляти об'єкти ArrayBuffer.
function sendArrayBuffer () {var xhr = new XMLHttpRequest (); xhr.open ( 'POST', '/ server', true); xhr.onload = function (e) {...}; var uInt8Array = new Uint8Array ([1, 2, 3]); xhr.send (uInt8Array.buffer); }Обмін ресурсами із запитом походження (Cross Origin Resource Sharing, або CORS)
За допомогою технології CORS веб-додатки можуть виконувати крос-доменні AJAX-запити до інших доменів. Зробити це дуже просто: достатньо, щоб сервер відправив необхідний заголовок відповіді.
Включення CORS-запитів
Припустимо, додаток знаходиться в домені example.com і потрібно отримати дані з домену www.example2.com. Як правило, при спробі відправити такий AJAX-запит він не виконується, а браузер видає помилку невідповідності походження. Завдяки технології CORS сайт www.example2.com може дозволити програмі з сайту example.com виконувати запити шляхом додавання одного заголовка.
Access-Control-Allow-Origin: http://example.comТема Access-Control-Allow-Origin можна додати як для одного сайту, так і для всього домену. Щоб увімкнути надсилання запитів з усіх доменів, додайте рядок такого виду:
Access-Control-Allow-Origin: *Фактично на всіх сторінках цього сайту (html5rocks.com) також використовується технологія CORS. Запустіть інструменти розробника, і у відповіді ви побачите заголовок Access-Control-Allow-Origin:
Тема Access-Control-Allow-Origin на сайті html5rocks.comДозволити крос-доменні запити нескладно, тому настійно рекомендується включати CORS для загальнодоступних даних.
Створення крос-доменного запиту
Якщо сервер-адресат підтримує CORS, крос-доменний запит нічим не відрізняється від звичайного запиту XMLHttpRequest. Наприклад, ось так маєте змогу надсилати запити з додатка на сервері example.com до сервера www.example2.com:
var xhr = new XMLHttpRequest (); xhr.open ( 'GET', 'http://www.example2.com/hello.json'); xhr.onload = function (e) {var data = JSON.parse (this.response); ...} xhr.send ();практичні приклади
Завантаження і збереження файлів в файлову систему HTML5
Припустимо, у вас є галерея зображень і ви хочете зберегти кілька картинок у себе за допомогою файлової системи HTML5 . Ви можете запросити ці картинки як об'єкти ArrayBuffer, створити на основі цих даних об'єкт Blob і записати його за допомогою FileWriter.
window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem; function onError (e) {console.log ( 'Error', e); } Var xhr = new XMLHttpRequest (); xhr.open ( 'GET', '/path/to/image.png', true); xhr.responseType = 'arraybuffer'; xhr.onload = function (e) {window.requestFileSystem (TEMPORARY, 1024 * 1024, function (fs) {fs.root.getFile ( 'image.png', {create: true}, function (fileEntry) {fileEntry.createWriter (function (writer) {writer.onwrite = function (e) {...}; writer.onerror = function (e) {...}; var bb = new BlobBuilder (); bb.append (xhr.response) ; writer.write (bb.getBlob ( 'image / png'));}, onError);}, onError);}, onError); }; xhr.send ();Зверніть увагу: для використання цього коду потрібно ознайомитися з умовами підтримки браузерів і обмеженнями на зберігання в керівництві Знайомство з API файлової системи .
Відправлення файлу по частинах
API файлів істотно полегшує відправку великих файлів. Методика така: великий файл розбивається на кілька дрібних, які потім відправляються за допомогою XHR і збираються назад на сервері. Приблизно так само Gmail швидко відправляє великі прикріплені файли. Ця технологія також дозволяє обійти обмеження Google App Engine: 32 МБ на один HTTP-запит.
window.BlobBuilder = window.MozBlobBuilder || window.WebKitBlobBuilder || window.BlobBuilder; function upload (blobOrFile) {var xhr = new XMLHttpRequest (); xhr.open ( 'POST', '/ server', true); xhr.onload = function (e) {...}; xhr.send (blobOrFile); } Document.querySelector ( 'input [type = "file"]'). AddEventListener ( 'change', function (e) {var blob = this.files [0]; const BYTES_PER_CHUNK = 1024 * 1024; // 1MB chunk sizes . const SIZE = blob.size; var start = 0; var end = BYTES_PER_CHUNK; while (start <SIZE) {// Note: blob.slice has changed semantics and been prefixed. See http://goo.gl/U9mE5. if ( 'mozSlice' in blob) {var chunk = blob.mozSlice (start, end);} else {var chunk = blob.webkitSlice (start, end);} upload (chunk); start = end; end = start + BYTES_PER_CHUNK;}}, false); }) ();Нижче наведено код для збірки файлу на сервері.
Перевірте, як він працює.