Статьи

New Tricks in XMLHttpRequest2 - HTML5 Rocks

  1. New Tricks in XMLHttpRequest2
  2. Вступ
  3. витяг даних
  4. Вказівка ​​формату відповіді
  5. Відповіді в форматі ArrayBuffer
  6. Відповіді в форматі Blob
  7. Відправка даних
  8. Відправка строкових даних: xhr.send (DOMString)
  9. Відправлення файлу або об'єкта Blob: xhr.send (Blob)
  10. Відправка довільного набору байтів: xhr.send (ArrayBuffer)
  11. Обмін ресурсами із запитом походження (Cross Origin Resource Sharing, або CORS)
  12. Включення CORS-запитів
  13. Створення крос-доменного запиту
  14. практичні приклади
  15. Відправлення файлу по частинах
  16. Корисні посилання
  17. Вступ
  18. витяг даних
  19. Вказівка ​​формату відповіді
  20. Відповіді в форматі ArrayBuffer
  21. Відповіді в форматі Blob
  22. Відправка даних
  23. Відправка строкових даних: xhr.send (DOMString)
  24. Відправлення файлу або об'єкта Blob: xhr.send (Blob)
  25. Відправка довільного набору байтів: xhr.send (ArrayBuffer)
  26. Обмін ресурсами із запитом походження (Cross Origin Resource Sharing, або CORS)
  27. Включення CORS-запитів
  28. Створення крос-доменного запиту
  29. практичні приклади
  30. Відправлення файлу по частинах
  31. Корисні посилання
  32. Вступ
  33. витяг даних
  34. Вказівка ​​формату відповіді
  35. Відповіді в форматі ArrayBuffer
  36. Відповіді в форматі Blob
  37. Відправка даних
  38. Відправка строкових даних: xhr.send (DOMString)
  39. Відправлення файлу або об'єкта Blob: xhr.send (Blob)
  40. Відправка довільного набору байтів: xhr.send (ArrayBuffer)
  41. Обмін ресурсами із запитом походження (Cross Origin Resource Sharing, або CORS)
  42. Включення CORS-запитів
  43. Створення крос-доменного запиту
  44. практичні приклади
  45. Відправлення файлу по частинах
  46. Корисні посилання
  47. Вступ
  48. витяг даних
  49. Вказівка ​​формату відповіді
  50. Відповіді в форматі ArrayBuffer
  51. Відповіді в форматі Blob
  52. Відправка даних
  53. Відправка строкових даних: xhr.send (DOMString)
  54. Відправлення файлу або об'єкта Blob: xhr.send (Blob)
  55. Відправка довільного набору байтів: xhr.send (ArrayBuffer)
  56. Обмін ресурсами із запитом походження (Cross Origin Resource Sharing, або CORS)
  57. Включення CORS-запитів
  58. Створення крос-доменного запиту
  59. практичні приклади
  60. Відправлення файлу по частинах
  61. Корисні посилання
  62. Вступ
  63. витяг даних
  64. Вказівка ​​формату відповіді
  65. Відповіді в форматі ArrayBuffer
  66. Відповіді в форматі Blob
  67. Відправка даних
  68. Відправка строкових даних: xhr.send (DOMString)
  69. Відправлення файлу або об'єкта Blob: xhr.send (Blob)
  70. Відправка довільного набору байтів: xhr.send (ArrayBuffer)
  71. Обмін ресурсами із запитом походження (Cross Origin Resource Sharing, або CORS)
  72. Включення CORS-запитів
  73. Створення крос-доменного запиту
  74. практичні приклади
  75. Відправлення файлу по частинах

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

Нижче наведено код для збірки файлу на сервері.

Перевірте, як він працює.

Корисні посилання

Новости