Статьи

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

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

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

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

Новости

Как создать фото из видео
Кризис заставляет искать дополнительные источники дохода. Одним из таких источников может стать торговля на валютном рынке Форекс. Но чтобы не потерять свои деньги необходимо работать с надежным брокером.

Как оформить группу в вконтакте видео
Дано хотел свой магазин в вк, но не знал с чего начать его делать. Так как хотелось не банальный магазин с кучей ссылок и фото, а красиво оформленный. С меню, с аватаркой. После просмотра видео создал

Как оформить диск малыш от рождения до года из фото и видео
Оформить диск "Малыш от рождения до года" из фото и видео можно совершенно разными способами! Кто-то для достижения данной цели идет на шоу-таланты, кто-то пользуется услугами профессионалов, а кто-то