Using the Web Animations API - Интерфейсы веб API

Using the Web Animations API
============================

Web Animations API позволяет нам создать анимацию и управлять её воспроизведением с помощью JavaScript. Эта статья будет правильным руководством для старта c весёлыми демками и уроками с Алисой в Стране Чудес.

Встречайте Web Animations API
-----------------------------

 В Web Animations API открывает анимацию на движке браузеров для разработчиков и манипуляции через (с помощью) JavaScript.
 Этот API был разработан в основе реализации CSS Animations и CSS Transitions (en-US), и оставлял свободу движений для будущих анимационных эффектов. Это один из самых эффективных способов анимации, поддерживаемой в Интернете, позволяя браузеру сделать свою собственную внутреннюю оптимизацию без хаков, принуждения, или `Window.requestAnimationFrame()`.

С Web Animations API, мы можем управлять интерактивной анимацией со стилями JavaScript, отделяя представление от действия. Нам больше не нужно полагаться на DOM-heavy методики написания CSS-свойств и обзорных классов для элементов контроля воспроизведения направления. И в отличии от чисто декларативного CSS, JavaScript также позволяет устанавливать динамические значения свойств и их продолжительность. Для создания пользовательских библиотек и интерактивной анимации Web Animations API может стать прекрасным инструментом в работе. Давайте посмотрим, что он может сделать!

Написание CSS Animations вместе с Web Animations API
----------------------------------------------------

Самый простой способ в обучении Web Animations API это начать с чего начинало большинство веб-разработчиков: CSS Animations. В CSS Animations есть знакомый синтаксис, который хорошо раскрывает структуры демонстрационных примеров.

### CSS версия

Вот такая анимация написана в CSS, показывающая, как Алиса падает в кроличью нору, которая ведёт в страну чудес (см. полный код на Codepen):

![Alice Tumbling down the rabbit's hole.](/ru/docs/Web/API/Web_Animations_API/Using_the_Web_Animations_API/tumbling-alice_optimized.gif)

Заметьте, что фон двигается, Алиса крутится и её цвет меняется при вращении. Мы собираемся сосредоточиться только на Алисе в этом уроке. Вот упрощённый код CSS, который управляет движением Алисы.

```css
#alice {
  animation: aliceTumbling infinite 3s linear;
}

@keyframes aliceTumbling {
  0% {
    color: #000;
    transform: rotate(0) translate3D(-50%, -50%, 0);
  }
  30% {
    color: #431236;
  }
  100% {
    color: #000;
    transform: rotate(360deg) translate3D(-50%, -50%, 0);
  }
}
```

Изменение цвета Алисы и её вращение в течение 3 секунд при постоянной (линейной) скорости и бесконечном цикле. В @keyframes (en-US) блоке мы видим, что 30% из всего цикла (около 9 секунд), цвет Алисы меняется от чёрного до насыщенного бордового, а потом снова в чёрный к концу цикла.

### Движение в JavaScript

Теперь давайте попробуем создать такую же анимацию с Web Animations API.

#### Представляя кадры

В первую очередь мы должны создать Keyframe Object (en-US) соответствующего нашему CSS @keyframes (en-US) блоку:

```js
var aliceTumbling = [
  { transform: "rotate(0) translate3D(-50%, -50%, 0)", color: "#000" },
  { color: "#431236", offset: 0.333 },
  { transform: "rotate(360deg) translate3D(-50%, -50%, 0)", color: "#000" },
];
```

Здесь мы используем массив, содержащий несколько объектов. Каждый объект представляет собой код от оригинального CSS. Однако, в отличие от CSS, Web Animations API не нужно назначать точные проценты по анимации для каждого открывающего кода. Он автоматически разделит анимацию на равные части в соответствии с количеством кодов, которые вы ему даёте. Это означает, что объект Keyframe с тремя кодами будет воспроизводить средний код 50% времени через каждый цикл анимации если не указано иное.

Если мы хотим, чтобы определённый набор кода смещался относительного другого кода, мы можем указать смещение непосредственно на объекте который будет меняться, отделив значение запятой. В приведённом выше примере видно, чтобы цвет Алисы менялся на 30%, а не на 50% всего цикла, мы задаём смещение: 0,333.

Там должно быть как минимум два кадра (представляющих начало и конец анимации). Если в вашем списке keyframe только одна запись, `Element.animate()` то анимация выполняться не будет, вы получите ошибку NotSupportedError exception.

И так повторим, код равномерно распределён по умолчанию, если не указано смещение. Удобно, не так ли?

#### Представление свойства времени

Мы также должны создать объекту временные свойства (an `AnimationEffectTimingProperties` (en-US) object) соответствующие значению анимации Алисы:

```js
var aliceTiming = {
  duration: 3000,
  iterations: Infinity,
};
```

Вы увидите здесь несколько отличий того, как соответствующие значения представлены в CSS:

* Во-первых, длительность в миллисекундах, в отличии от секунд - 3000, а не 3с. Как `WindowTimers.setTimeout()` и `Window.requestAnimationFrame()`, Web Animations API использует только миллисекунды.
* Во-вторых, что вы заметили, что он итерационный (повторяется), а не счётчик повторений.

**Примечание:** Существует ряд небольших различий между терминологией, используемой в анимации CSS и терминологии, которая используется в веб-анимации. Например, веб-анимации не используется строка "бесконечное", а вместо этого использует JavaScript-код бесконечность. И вместо временной-функции мы используем ослабление. Мы не будем перечислять здесь значение ослабления, потому что, в отличие от CSS-анимации, где по умолчанию animation-timing-function это просто, в веб-анимации API для ослабления по умолчанию используется линейная зависимость - которые мы используем здесь

#### Собираем части вместе

Сейчас соберём все части вместе используя `Element.animate()` метод:

```js
document.getElementById("alice").animate(aliceTumbling, aliceTiming);
```

И вуаля, анимация работает(смотрите готовый вариант на version on Codepen).

The `animate()` метод может быть применён на любой DOM-элемент, который может быть анимирован с помощью CSS. И он может быть записан несколькими способами. Вместо того, чтобы делить объекты на ключевые кадры и временные характеристики, мы могли бы просто передать свои значения непосредственно вот так:

```js
document.getElementById("alice").animate(
  [
    { transform: "rotate(0) translate3D(-50%, -50%, 0)", color: "#000" },
    { color: "#431236", offset: 0.333 },
    { transform: "rotate(360deg) translate3D(-50%, -50%, 0)", color: "#000" },
  ],
  {
    duration: 3000,
    iterations: Infinity,
  },
);
```

Более того, если мы хотели указать только длительность анимации, а не её повторение (по умолчанию анимации повторяется один раз), мы могли бы пройтись только по миллисекундам:

```js
document.getElementById("alice").animate(
  [
    { transform: "rotate(0) translate3D(-50%, -50%, 0)", color: "#000" },
    { color: "#431236", offset: 0.333 },
    { transform: "rotate(360deg) translate3D(-50%, -50%, 0)", color: "#000" },
  ],
  3000,
);
```

Управление воспроизведением с помощью play(), pause(), reverse() and playbackRate
---------------------------------------------------------------------------------

Хотя мы можем писать CSS-анимацию с Web Animations API, где API действительно хорошо подходит в качестве воздействия для воспроизведения анимации. Web Animations API обеспечивает несколько удобных методов для контроля воспроизведения анимации. Давайте посмотрим на паузу и воспроизведение анимации в росте/уменьшении Алисы в игре (проверить полный код можно на сайте full code on Codepen):

![Playing the growing and shrinking game with Alice.](/ru/docs/Web/API/Web_Animations_API/Using_the_Web_Animations_API/growing-shrinking_article_optimized.gif)

В этой игре Алиса меняется в росте, она то растёт, то уменьшается, а контролируем мы этот процесс с помощью бутылки и кекса. Каждый из них имеют свою анимацию.

### Пауза и проигрывание анимации

Мы поговорим об анимации Алисы позже, а сейчас посмотрим поближе на анимации кекса:

```js
var nommingCake = document
  .getElementById("eat-me\_sprite")
  .animate(
    [{ transform: "translateY(0)" }, { transform: "translateY(-80%)" }],
    {
      fill: "forwards",
      easing: "steps(4, end)",
      duration: aliceChange.effect.timing.duration / 2,
    },
  );
```

Метод `Element.animate()` будет выполняться сразу же как начнётся игра. Чтобы предотвратить автоматическое поедание кекса до того, как пользователь на него нажмёт, мы вызываем `Animation.pause()` (en-US) сразу же как игра открывается, например так:

```js
nommingCake.pause();
```

Теперь мы можем запустить метод `Animation.play()` (en-US) когда будем готовы:

```js
nommingCake.play();
```

Нам необходимо связать его с анимацией Алисы, чтобы она росла всякий раз, когда съедала кекс. Мы можем сделать это с помощью функции:

```js
var growAlice = function () {
  // Play Alice's animation.
  aliceChange.play();

  // Play the cake's animation.
  nommingCake.play();
};
```

Когда пользователь поместит указатель мыши вниз или нажимает пальцем на торт на сенсорном экране, мы можем вызвать growAlice, чтобы выполнить все анимации:

```js
cake.addEventListener("mousedown", growAlice, false);
cake.addEventListener("touchstart", growAlice, false);
```

### Другие полезные методы

Помимо паузы и воспроизведения, мы можем использовать следующие методы анимации:

* `Animation.finish()` (en-US) перейти в конец анимации.
* `Animation.cancel()` прервать анимацию и удалить её эффект.
* `Animation.reverse()` (en-US) устанавливать скорость анимации если установить (`Animation.playbackRate` (en-US) отрицательное значение, то анимация пойдёт в обратном порядке.

Давайте посмотрим на первый playbackRate— отрицательное значение будет запускать анимацию в обратном направлении. Когда Алиса пьёт из бутылки, она становится меньше. Это происходит потому, что бутылка изменяет её анимацию playbackRate от 1 до -1:

```js
var shrinkAlice = function () {
  aliceChange.playbackRate = -1;
  aliceChange.play();
};

bottle.addEventListener("mousedown", shrinkAlice, false);
bottle.addEventListener("touchstart", shrinkAlice, false);
```

В Through the Looking-Glass, Алиса путешествует по миру, где должна бежать, чтобы оставаться на месте и бежать в двое быстрее, чтобы двигаться вперёд. Например в гонке с Красной королевой, Алиса и Красная королева бегут, чтобы оставаться на месте (проверить полный код можно на full code on Codepen):

![Alice and the Red Queen race to get to the next square in this game.](/ru/docs/Web/API/Web_Animations_API/Using_the_Web_Animations_API/red-queen-race_optimized.gif)

Так как маленькие дети легко устают, в отличии от шахматных фигур, Алиса постоянно замедляется. Мы отобразили это в коде путём ослабления (уменьшения скорости) playbackRate анимации.

```js
setInterval(function () {
  // Make sure the playback rate never falls below .4
  if (redQueen_alice.playbackRate > 0.4) {
    redQueen_alice.playbackRate \*= 0.9;
  }
}, 3000);
```

Но постоянно нажимая на них мышью, мы заставляем их ускориться путём умножения playbackRate (скорости анимации)

```js
var goFaster = function () {
  redQueen_alice.playbackRate \*= 1.1;
};

document.addEventListener("click", goFaster);
document.addEventListener("touchstart", goFaster);
```

Фон также ускоряется при щелчках мыши или касаниях. Что же происходит, когда вы заставляете Алису и Красную королеву бежать в два раза быстрее? Что происходит, когда они тормозят?

Получение информации из анимации
--------------------------------

Представьте, что мы могли бы использовать playbackRate, как улучшения доступности сайта для пользователей с вестибулярными расстройствами, позволяя им замедлить анимацию на всех страницах сайта. Это невозможно сделать с помощью CSS без пересчёта длительности в каждом правиле CSS, но с веб-анимации API, мы могли бы использовать в будущем (пока не поддерживается в браузерах!) Метод `document.getAnimations()` (en-US) систему циклов по каждой анимации на странице и сократить скорость анимации вот так:

```js
document.getAnimations().forEach(function (animation) {
  animation.playbackRate \*= 0.5;
});
```

С Web Animations API нужно изменить только одно свойство.

Другое дело, что это трудно делать только с CSS Animations, создавать зависимости от значения предусмотренные для других анимации. В примере игры про рост и уменьшение Алисы, вы можете заметить некоторые странности у кекса:

```js
duration: aliceChange.effect.timing.duration / 2;
```

Чтобы понять, что здесь происходит, давайте посмотрим на анимацию Алисы:

```js
var aliceChange = document
  .getElementById("alice")
  .animate(
    [
      { transform: "translate(-50%, -50%) scale(.5)" },
      { transform: "translate(-50%, -50%) scale(2)" },
    ],
    {
      duration: 8000,
      easing: "ease-in-out",
      fill: "both",
    },
  );
```

Изменение размера Алисы в два раза происходит за 8 секунд. Затем мы останавливаем её:

```js
aliceChange.pause();
```

Если бы оставили её на паузе в начале анимации , то Алиса увеличилась бы в два раза, когда выпила бы всю бутылку. Мы хотим остановить её анимацию "воспроизведение" в середине, когда она уже на половину выполнена. Мы могли бы это сделать, установив `Animation.currentTime` (en-US) 4 секунды, вот так:

```js
aliceChange.currentTime = 4000;
```

Но во время работы над этой анимацией мы можем сильно увеличить её продолжительность. Разве не лучше установить динамическое изменение времени (currentTime), тогда нам не придётся делать два обновления за один раз. Мы можем это сделать с помощью ссылки на изменение свойства размера Алисы (aliceChange) `Animation.effect` (en-US) который возвращает все детали и действующие эффекты, содержащиеся в объекте, на Алису:

```js
aliceChange.currentTime = aliceChange.effect.timing.duration / 2;
```

эффекты позволяют нам получить доступ к анимации keyframe (кадров) и синхронности объектов - aliceChange.effect.timing , указывающий на время Алисиных элементов (которые имеют тип `AnimationEffectTimingReadOnly`) — в этом содержится её `AnimationEffectTimingReadOnly.duration`. Мы можем распределить её длительность на два раза, чтобы получить среднюю точку во временной шкале для установки нормального роста.

Теперь мы можем запустить её в обратном порядке и играться анимацией в любом направлении, чтобы заставить её расти или уменьшаться

```js
var drinking = document
  .getElementById("liquid")
  .animate([{ height: "100%" }, { height: "0" }], {
    fill: "forwards",
    duration: aliceChange.effect.timing.duration / 2,
  });
drinking.pause();
```

И мы можем сделать тоже самое при установки длительности анимации на кексе или бутылке.

Теперь все три анимации связаны только с одной продолжительности, и мы можем легко переходить из одного места.

Мы также можем использовать веб-анимации API, чтобы выяснить Текущее время анимации. Игра заканчивается, когда вы бежите от съеденного торта или выпитой бутылки. Изображение у игрока будет зависеть от анимации Алисы. Стала ли она слишком большой на фоне крошечной двери и не может в неё пройти или слишком маленькой и не может достать ключ, чтобы открыть дверь. Мы можем выяснить, стала она большой или маленький в конце её анимация, получая текущее время её анимации `currentTime` (en-US) и разделив её на activeDuration:

```js
var endGame = function() {

  // get Alice's timeline's playhead location
  var alicePlayhead = aliceChange.currentTime;
  var aliceTimeline = aliceChange.effect.activeDuration;

  // stops Alice's and other animations
  stopPlayingAlice();

  // depending on which third it falls into
  var aliceHeight = alicePlayhead/aliceTimeline;

  if (aliceHeight <= .333){
    // Alice got smaller!
    ...

  } else if (aliceHeight >= .666) {
    // Alice got bigger!
    ...

  } else {
    // Alice didn't change significantly
    ...

  }
}
```

**Примечание:** `getAnimations()` и эффект не полностью поддерживаются на момент написания этой статьи, но polyfill поддерживает их уже сегодня.

Колбэки и промисы
-----------------

CSS Animations и Transitions (переходы) имеют свои события и они также могут быть воспроизведены и в Web Animations API:

* `onfinish` (en-US) это обработчик события завершения анимации, он может быть запущен вручную с помощью метода `finish()` (en-US).
* `oncancel` (en-US) это обработчик события отмены анимации, он может быть запущен вручную с помощью метода `cancel()`.

Здесь мы устанавливаем колбэк для бутылки, кекса и Алисы, чтобы запустить функцию endGame.

```js
// When the cake or runs out...
nommingCake.onfinish = endGame;
drinking.onfinish = endGame;

// ...or Alice reaches the end of her animation
aliceChange.onfinish = endGame;
```

Нравится перспектива? Web Animations API также даёт две перспективы: `onfinish` (en-US) и `oncancel` (en-US).

**Примечание:** Эти промисы не полностью поддерживаются в настоящий момент.

Заключение
----------

Таковы основные особенности веб-анимации API, большинство из которых уже поддерживается в последних версиях Firefox и Chrome. К этому моменту вы должны быть готовы к "прыжку в кроличью нору" анимации в браузере и готовы написать свои собственные эксперименты в анимации! Если вы используете API и хотите поделиться, попробуйте использовать хештег #WAAPI. Мы будем следить и писать другие учебники, чтобы охватить будущие дополнительные функции, в виде поддержки распространяя!

Посмотрите также
----------------

* Полный набор Алиса в Стране Чудес демки на сайт codepen для вас, чтобы играть, развиваться и делиться
* Animating like you just don't care with Element.animate — отличная статья, чтобы прочитать, где объясняется больше на фоне веб-анимации API, и поэтому он является более эффективным, чем другие методы веб-анимации
* web-animations-js — the Web Animations API polyfill


StyleSheet.disabled - Интерфейсы веб API

StyleSheet.disabled
===================

Свойство **`disabled`** интерфейса `StyleSheet` определяет будет ли таблица стилей защищена от применения в документе

Таблицу стилей можно отключить, установив для этого свойства значение `true`, или, если она неактивна, с помощью альтернативной таблице стилей (en-US). Заметьте, что `disabled == false` не гарантирует применение таблице стилей (она может быть удалена из документа, к примеру).

Синтаксис
---------
```

bool = stylesheet.disabled
```

Пример
------

```js
// Если таблица стилей отключена...
if (stylesheet.disabled) {
  // ... применять стили в строке.
}
```

Спецификация
------------

| Specification |
| --- |
| CSS Object Model (CSSOM) # dom-stylesheet-disabled |

Совместимость с браузерами
--------------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


MediaRecorder.state - Интерфейсы веб API

MediaRecorder.state
===================

Свойство только для чтения **`MediaRecorder.state`** возвращает текущее состояние определённого объекта `MediaRecorder`.

Синтаксис
---------
```

var state = MediaRecorder.state
```

### Значения

Объект AnimationPlayState содержит одно из нижеперечисленных значений:

| Значение | Описание |
| --- | --- |
| `inactive` | Запись не ведётся — она ещё не была начата или уже была осуществлена и остановлена. |
| `recording` | Запись начата и UA собирает данные. |
| `paused` | Запись была начата, но поставлена на паузу, не остановлена и ещё не возобновлена. |

Пример
------

```js
...

  record.onclick = function() {
    mediaRecorder.start();
    console.log(mediaRecorder.state);
    // Должно вернуть "recording"
    console.log("захват начат");
  }

...
```

Спецификации
------------

| Specification |
| --- |
| MediaStream Recording # dom-mediarecorder-state |

Совместимость с браузерами
--------------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

Смотрите также
--------------

* Использование MediaRecorder API (en-US)
* Веб-диктофон: MediaRecorder + getUserMedia + Web Audio API от Chris Mills (исходники на Github.)
* simpl.info Демонстрация MediaStream Recording от Sam Dutton.
* `Navigator.getUserMedia`


MediaRecorder.requestData() - Интерфейсы веб API

MediaRecorder.requestData()
===========================

Метод **`MediaRecorder.requestData()`** (часть MediaRecorder API (en-US)) используется, чтобы поднять `dataavailable` событие содержащее `Blob` объект захваченных медиа-данных как это было когда метод был вызван. This can then be grabbed и манипулировать как необходимо.

When the `requestData()` method is invoked, the browser queues a task that runs the following steps:

1. If `MediaRecorder.state` is not "recording", raise a DOM `InvalidState` error and terminate these steps. If `MediaRecorder.state` is "recording", continue to the next step.
2. Raise a `dataavailable` event containing a `Blob` of the currently captured data (the Blob is available under the event's `data` attribute.)
3. Create a new Blob and place subsequently captured data into it.
Syntax
------
```

MediaRecorder.requestData()
```

### Errors

An `InvalidState` error is raised if the `requestData()` method is called while the `MediaRecorder` object's `MediaRecorder.state` is not "recording" — the media cannot be captured if recording is not occurring.

Example
-------

```js
...

  captureMedia.onclick = function() {
    mediaRecorder.requestData();
    // makes snapshot available of data so far
    // ondataavailable fires, then capturing continues
    // in new Blob
  }

...
```

Specifications
--------------

| Specification |
| --- |
| MediaStream Recording # dom-mediarecorder-requestdata |

Совместимость с браузерами
--------------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Using the MediaRecorder API (en-US)
* Web Dictaphone: MediaRecorder + getUserMedia + Web Audio API visualization demo, by Chris Mills (source on Github.)
* simpl.info MediaStream Recording demo, by Sam Dutton.
* `Navigator.getUserMedia`


MediaRecorder.MediaRecorder() - Интерфейсы веб API

MediaRecorder.MediaRecorder()
=============================

**`MediaRecorder()`** конструктор `MediaRecorder` объекта который будет делать запись переданного `MediaStream`.

Синтаксис
---------
```

var mediaRecorder = new MediaRecorder(stream[, options]);
```

### Параметры

**`stream`**

Объект потока `MediaStream` источника из которого будет производиться запись. Может быть потоком, созданным `navigator.mediaDevices.getUserMedia()` или `<audio>`, `<video>` или `<canvas>` элементами.

**`options`** Необязательный

Объект, содержащий следующие свойства:

* `mimeType`: `mime` тип, определяет формат результата записи, который нужно использовать в качестве контейнера для создаваемого объекта `MediaRecorder`. Можно просто указать формат контейнера, а браузер сам выберет нужный кодек для записи аудио/видео, или используйте параметр codecs или параметр `profiles` для расширения информации об использовании и тонкой конфигурации кодеков. Приложения, предварительно, могут проверять поддержку браузерами определённого типа из свойства `mimeType` , вызывая метод `MediaRecorder.isTypeSupported()` (en-US).
* `audioBitsPerSecond`: Скорость записи медиа данных аудио.
* `videoBitsPerSecond`: Скорость записи медиа данных видео.
* `bitsPerSecond`: Скорость записи медиаданных аудио и видео. Может определяться вместо верхних двух. Если определяется вместе с одним из свойств выше, имеет меньший приоритет, и используется вместо отсутствующей настройки выше..

**Примечание:** Если значения битов в секунду не указаны для видео и / или аудио, для видео по умолчанию принимается значение 2,5 Мбит / с, а для аудио по умолчанию используется адаптивный режим, в зависимости от частоты дискретизации и количества каналов.

### Исключения

`NotSupportedError`

Определяет MIME тип, не поддерживающийся браузером.

Пример
------

В этом примере показано, как создать медиа рекордер для указанного потока, чья скорость передачи звука составляет 128 Кбит / с, а скорость передачи видео - 2,5 Мбит / с. Записанные мультимедийные данные будут храниться в контейнере MP4 (поэтому, если вы соберёте порции мультимедийных данных и сохраните их на диск, они будут в файле с разрешением MP4).

```js
...

if (navigator.mediaDevices.getUserMedia) {
  var constraints = { audio: true, video: true };
  var chunks = [];

  var onSuccess = function(stream) {
    var options = {
      audioBitsPerSecond : 128000,
      videoBitsPerSecond : 2500000,
      mimeType : 'video/mp4'
    }
    var mediaRecorder = new MediaRecorder(stream,options);
    m = mediaRecorder;

...
```

Спецификации
------------

| Specification |
| --- |
| MediaStream Recording # dom-mediarecorder-mediarecorder |

Совместимость с браузерами
--------------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

Смотрите также
--------------

* Использование MediaRecorder API (en-US)
* Веб диктофон: MediaRecorder + getUserMedia + Web Audio API visualization demo, by Chris Mills (source on Github.)
* simpl.info MediaStream Recording demo, by Sam Dutton.
* `Navigator.mediaDevices.getUserMedia()` (en-US)


MediaRecorder.start() - Интерфейсы веб API

MediaRecorder.start()
=====================

Метод **`MediaRecorder.start()`** (часть MediaRecorder API (en-US)) используется для начала захвата медиа `Blob`.

When the `start()` method is invoked, the UA queues a task that runs the following steps:

1. If the `MediaRecorder.state` is not "inactive", raise a DOM `InvalidState` error and terminate these steps. if the `MediaRecorder.state` is "inactive", continue on to the next step.
2. Set the `MediaRecorder.state` to "recording" and wait until media becomes available from the `stream` passed into `Navigator.getUserMedia`.
3. Once data becomes available, raise a `MediaRecorder.start` event and start gathering the data into a `Blob` (see FILE-API).
4. If the `timeSlice` argument has been provided, once that many milliseconds of data have been collected — or a minimum time slice imposed by the UA, whichever is greater — raise a `MediaRecorder.dataavailable` event containing the Blob of collected data, and start gathering a new Blob of data. If `timeSlice` has not been provided, continue gathering data into the original Blob.
5. When the `stream` is ended, set `MediaRecorder.state` to "inactive" and stop gathering data.
6. Raise a `MediaRecorder.dataavailable` event containing the Blob of data.
7. Raise a `MediaRecorder.stop` (en-US) event.

**Примечание:** If the browser is unable to start recording or continue recording, it *will* raise a `DOMError` (en-US) event, followed by a `MediaRecorder.dataavailable` event containing the Blob it has gathered, followed by the `MediaRecorder.stop` (en-US) event.

Синтаксис
---------
```

MediaRecorder.start(timeslice)
```

### Параметры

`timeslice` Необязательный

Этот параметр принимает значение в миллисекундах, и переопределяет длину куска захвата медиа для возвращения в каждом Blob. Если не указан, то все медиа данные будут занесены в один Blob, только если не был вызван метод `MediaRecorder.requestData`.

### Ошибки

An `InvalidState` error is raised if the `start()` method is called while the `MediaRecorder` object's `MediaRecorder.state` is not "inactive" — it makes no sense to start media capture if it is already happening.

Пример
------

```js
...

  record.onclick = function() {
    mediaRecorder.start();
    console.log("рекордер запущен");
  }

...
```

Specifications
--------------

| Specification |
| --- |
| MediaStream Recording # dom-mediarecorder-start |

Совместимость с браузерами
--------------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

Смотрите также
--------------

* Использование MediaRecorder API (en-US)
* Веб-диктофон: MediaRecorder + getUserMedia + Web Audio API от Chris Mills (исходники на Github.)
* simpl.info Пример использования MediaStream от Sam Dutton.
* `Navigator.getUserMedia`


MediaRecorder.ondataavailable - Интерфейсы веб API

MediaRecorder.ondataavailable
=============================

**`MediaRecorder.ondataavailable`** обработчик события (часть MediaStream Recording API) обрабатывает `dataavailable` событие, позволяет выполнить код, когда тип данных `Blob`, представляющий обработанные данные становиться доступным для использования.

Событие `dataavailable` вызывается когда MediaRecorder доставляет медиа данные в ваше приложение для использования. Они представляются в виде объекта типа `Blob`, содержащего данные. Это происходит в четырёх ситуациях:

* Когда медиа поток завершается, любые мультимедийные данные ещё не доставленные в обработчик `ondataavailable` немедленно передаются в объект `Blob`.
* При вызове метода `MediaRecorder.stop()` (en-US) , порция медиаданных, объем которых был захвачен с момента начала записи или после последнего вызова события `dataavailable` помещаются в объект `Blob`; после этого захват завершается.
* При вызове метода `MediaRecorder.requestData()` порция медиаданных, объем которых был захвачен с момента начала записи, или после последнего вызова события `dataavailable` помещаются в вновь созданный объект типа `Blob` , и захват порций медиаданных продолжается уже в этот новый объект `blob`.
* Если свойство `timeslice` передаётся в метод `MediaRecorder.start()`, который запускает захват порций медиаданных, событие `dataavailable` запускается каждые `timeslice` миллисекунд. Это значит, что каждый объект типа `blob` будет иметь специфический размер (за исключением последнего, который может быть короче, содержащий все, что осталось с момента последнего события ). Поэтому, если метод выглядит так : `recorder.start(1000);` то событие `dataavailable` будет запускаться каждую секунду общего потока медиа захвата, и обработчик события будет вызываться каждую секунду, содержащий в параметре объект типа `blob` , который будет содержать объем порции записи медиаданных продолжительностью в одну секунду. Можно использовать свойство `timeslice` вместе с `MediaRecorder.stop()` (en-US) и `MediaRecorder.requestData()` для создания нескольких объектов типа `blob` одинакового объёма данных , плюс последние короткие объекты типа `blob.`

**Примечание:** Медиаданные, содержащиеся в объекте типа `Blob` доступны в свойстве `data` , возвращаемого в параметре объекта события `dataavailable`.

Синтаксис
---------
```

MediaRecorder.ondataavailable = function(event) { ... }
MediaRecorder.addEventListener('dataavailable', function(event) { ... })
```

Пример
------

```js
...

  mediaRecorder.onstop = function(e) {
    console.log("data available after MediaRecorder.stop() called.");

    var audio = document.createElement('audio');
    audio.controls = true;
    var blob = new Blob(chunks, { 'type' : 'audio/ogg; codecs=opus' });
    var audioURL = window.URL.createObjectURL(blob);
    audio.src = audioURL;
    console.log("recorder stopped");
  }

  mediaRecorder.ondataavailable = function(e) {
    chunks.push(e.data);
  }

...
```

Спецификации
------------

| Specification |
| --- |
| MediaStream Recording # dom-mediarecorder-ondataavailable |

Совместимость с браузерами
--------------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

Смотрите также
--------------

* Использование интерфейса записи медиапотока
* Веб диктофон: MediaRecorder + getUserMedia + Web Audio API пример визуализации, от Chris Mills (source on Github.)
* Демонстрационный пример записи медиапотока, от Sam Dutton.
* `Navigator.getUserMedia`


VRDisplayCapabilities.hasPosition - Интерфейсы веб API

VRDisplayCapabilities.hasPosition
=================================

**Устарело:** Эта возможность была удалена из веб-стандартов. Хотя некоторые браузеры по-прежнему могут поддерживать её, она находится в процессе удаления. Не используйте её ни в старых, ни в новых проектах. Страницы или веб-приложения, использующие её, могут в любой момент сломаться.

**Не стандартно:** Эта возможность не является стандартной и стандартизировать её пока никто не собирается. Не используйте её на сайтах, смотрящих во внешний мир: она будет работать не у всех пользователей. Также могут присутствовать большие несовместимости между реализациями и её поведение может в будущем измениться.

Доступное только для чтения свойство **`hasPosition`** интерфейса `VRDisplayCapabilities` возвращает `true` если VR-устройство может отслеживать и возвращать информацию о своём местоположении.

**Примечание:** Это свойство было частью старого WebVR API, который был заменён на WebXR Device API.

### Значение

`Boolean` (en-US).

Примеры
-------

Смотрите примеры использования в `VRDisplayCapabilities`.

Спецификации
------------

Это свойство было частью старого WebVR API, который был заменён на WebXR Device API. Больше не планируется сделать его стандартом.

Пока все браузеры не реализуют новые WebXR API (en-US), рекомендуется использовать такие фреймворки как A-Frame, Babylon.js, Three.js или полифил для разработки приложений WebXR, которые будут работать во всех браузерах.

Совместимость с браузерами
--------------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

Смотрите также
--------------

* WebVR API.


Написание клиентских приложений с помощью веб-сокетов - Интерфейсы веб API

Написание клиентских приложений с помощью веб-сокетов
=====================================================

Веб-сокеты - технология, которая позволяет открыть интерактивную сессию общения между браузером пользователя и сервером. Соединяясь через веб-сокеты, веб-приложения могут осуществлять взаимодействие в реальном времени вместо того, чтобы делать запросы к клиенту о входящих/исходящих изменениях.

**Примечание:** У нас есть работающий пример чата, части кода из которого используются в статье. Пример будет доступен, когда инфраструктура сайта сможет должным образом поддерживать хостинг примеров с использованием веб-сокетов.

Доступность веб-сокетов
-----------------------

API веб-сокетов доступно в Javascript коде, область видимости которого включает объект DOM `Window` или любой объект, реализующий `WorkerUtils`; это означает, что вы можете использовать Web Workers.

**Примечание:** API веб-сокетов (как и протокол лежащий в его основе) всё ещё проходят этап активной разработки; в настоящее время существует много проблем совместимости с разными браузерами (и даже с разными релизами одного и того же браузера).

Создание объекта WebSocket
--------------------------

`Чтобы общаться через протокол веб-сокетов необходимо создать объект WebSocket`; при его создании автоматически происходит попытка открыть соединение с сервером.

Конструктор WebSocket принимает один обязательный и один необязательный параметр:
```

WebSocket WebSocket(
  in DOMString url,
  in optional DOMString protocols
);

WebSocket WebSocket(
  in DOMString url,
  in optional DOMString[] protocols
);
```

`url`

URL, с которым происходит соединение; это должен быть URL веб-сокет-сервера.

`protocols` Необязательный

Может быть одной строкой протокола или массивом таких строк. Эти строки используют для индикации под-протоколов; таким образом, один сервер может реализовывать несколько под-протоколов веб-сокетов (к примеру, вам может потребоваться, чтобы сервер мог обрабатывать разные типы взаимодействий в зависимости от определённого под-протокола). Если вы не укажете строку протокола, то будет передана пустая строка.

В конструкторе могут возникать следующие исключения:

`SECURITY_ERR`

Порт, к которому проводится подключение, заблокирован.

### Ошибки подключения

Если ошибка случается во время попытки подключения, то в объект `WebSocket` сначала посылается простое событие с именем «error» (таким образом, задействуя обработчик `onerror`), потом - событие `CloseEvent` (таким образом, задействуя обработчик `onclose`) чтобы обозначить причину закрытия соединения.

Однако, начиная с версии Firefox 11, типичным является получение в консоль от платформы Mozilla расширенного сообщения об ошибке и кода завершения, как то определено в RFC 6455, Section 7.4 посредством `CloseEvent`.

### Примеры

Этот простой пример создаёт новый WebSocket, подключаемый к серверу `ws://www.example.com/socketserver`. В данном примере в конструктор сокета в качестве дополнительного параметра передаётся пользовательский протокол "protocolOne", хотя эта часть может быть опущена.

```js
var exampleSocket = new WebSocket(
  "ws://www.example.com/socketserver",
  "protocolOne",
);
```

После выполнения функции, `exampleSocket.readyState` (en-US) будет иметь значение `CONNECTING`. `readyState` изменится на `OPEN` как только соединение станет готовым к передаче данных.

Если нужно открыть соединение, поддерживающее несколько протоколов, можно передать массив протоколов:

```js
var exampleSocket = new WebSocket("ws://www.example.com/socketserver", [
  "protocolOne",
  "protocolTwo",
]);
```

Когда соединение установлено (что соответствует, `readyState` `OPEN`), `exampleSocket.protocol` сообщит, какой протокол выбрал сервер.

В приведенных выше примерах `ws` заменяет `http`, аналогично `wss` заменяет `https`. Установка соединения через WebSocket зависит от механизма обновления HTTP, таким образом запрос на обновление неявный, когда мы обращаемся к серверу HTTP с помощью `ws://www.example.com` или `wss://www.example.com`.

Отправка данных на сервер
-------------------------

Однажды открыв соединение, вы можете передавать данные на сервер. Для осуществления этого, вызовите метод `send()` объекта `WebSocket` для каждого сообщение, которое желаете отправить:

```js
exampleSocket.send("Вот текст, который будет отправлен серверу.");
```

Вы можете пересылать данные в виде строки, `Blob`, так и `ArrayBuffer`.

**Примечание:** До версии 11, Firefox поддерживал отправку данных только в виде строки.

Так как установка соедиения асинхронна и подвержена сбоям, то нет никакой гарантии, что вызов метода `send()`, после создания объекта WebSocket, будет завершен успешно. По крайней мере, мы можем быть уверены, что попытка отправить данные будет иметь место только после того, как соединение будет установлено, определив обработчик `onopen` для выполнения этого действия:

```js
exampleSocket.onopen = function (event) {
  exampleSocket.send("Вот текст, который будет отправлен серверу.");
};
```

### Использование JSON для передачи объектов

Одна удобная вещь которую вы можете сделать, это использовать JSON для пересылки сложных данных на сервер. Например, приложение-чат может взаимодействовать с сервером, используя протокол, реализованный с использованием пакетов данных, инкапсулированных в JSON:

```js
// Отправьте текст всем пользователям через сервер
function sendText() {
  // Создайте объект содержащий данные, необходимые серверу для обрабоки сообщения от клиента чата.
  var msg = {
    type: "message",
    text: document.getElementById("text").value,
    id: clientID,
    date: Date.now(),
  };

  // Отправьте объект в виде JSON строки.
  exampleSocket.send(JSON.stringify(msg));

  // Очистите элемент ввода текста, чтобы получить следующую строку текста от пользователя.
  document.getElementById("text").value = "";
}
```

Получение сообщений от сервера
------------------------------

WebSockets — это API, управляемый событиями; когда сообщения получены, событие "message" доставлено в функцию `onmessage`. Чтобы начать прослушивание входящих данных, вы можете сделать что-то вроде этого:

```js
exampleSocket.onmessage = function (event) {
  console.log(event.data);
};
```

### Получение и интерпретация JSON объектов

Давайте рассмотрим клиентское приложение чата, которое впервые упоминалось в разделе Использование JSON для передачи объектов. Есть разные типы пакетов данных, которые может получить клиент, например:

* Вход в систему
* Текст сообщения
* Обновление списка пользователей

Код обрабатывающий эти входящие сообщения, может выглядеть так:

```js
exampleSocket.onmessage = function (event) {
  var f = document.getElementById("chatbox").contentDocument;
  var text = "";
  var msg = JSON.parse(event.data);
  var time = new Date(msg.date);
  var timeStr = time.toLocaleTimeString();

  switch (msg.type) {
    case "id":
      clientID = msg.id;
      setUsername();
      break;
    case "username":
      text =
        "<b>User <em>" +
        msg.name +
        "</em> signed in at " +
        timeStr +
        "</b><br>";
      break;
    case "message":
      text = "(" + timeStr + ") <b>" + msg.name + "</b>: " + msg.text + "<br>";
      break;
    case "rejectusername":
      text =
        "<b>Your username has been set to <em>" +
        msg.name +
        "</em> because the name you chose is in use.</b><br>";
      break;
    case "userlist":
      var ul = "";
      for (i = 0; i < msg.users.length; i++) {
        ul += msg.users[i] + "<br>";
      }
      document.getElementById("userlistbox").innerHTML = ul;
      break;
  }

  if (text.length) {
    f.write(text);
    document.getElementById("chatbox").contentWindow.scrollByPages(1);
  }
};
```

Здесь мы используем `JSON.parse()` чтобы преобразовать JSON строку в объект, затем обработайте его.

### Формат текстовых данных

Текст, полученный через WebSocket должен иметь кодировку UTF-8

До Gecko 9.0, некоторые не символьные значения в допустимом тексте UTF-8 могут привести к разрыву соединения. Теперь Gecko допускает эти значения.

Закрытие соединения
-------------------

Когда вы закончили использовать соединение WebSocket, закройте его используя метод `close()`:

```js
exampleSocket.close();
```

Перед попыткой закрыть соединение может быть полезно проверить атрибут `bufferedAmount` чтобы определить, не переданы ли еще какие-либо данные по сети.

Безопасность
------------

WebSocket не следует использовать в среде со смешанным содержимым: то есть вы не должны открывать незащищенное соединение WebSocket со страницы, загруженной с использованием HTTPS, или наоборот. Фактически, некоторые браузеры явно запрещают это, например Firefox 8 и выше.


BackgroundFetchManager.fetch() - Интерфейсы веб API

BackgroundFetchManager.fetch()
==============================

Limited availability
--------------------

This feature is not Baseline because it does not work in some of the most widely-used browsers.

* Learn more
* See full compatibility
* Report feedback
Метод **`fetch()`** интерфейса `BackgroundFetchManager` возвращает `Promise`, результатом обработки которого будет объект `BackgroundFetchRegistration` для переданного массива URL-адресов или объектов `Request`.

Синтаксис
---------

```js
fetch(id, requests);
fetch(id, requests, options);
```

### Параметры

`id`

Определяемый разработчиком идентификатор, который может быть передан другим методам для получения `backgroundFetchRegistration`.

`requests`

Объект `RequestInfo` или массив таких объектов.

`options` Необязательный

Объект `BackgroundFetchOptions`.

### Возвращаемое значение

`Promise`, результатом обработки которого будет объект `BackgroundFetchRegistration`.

### Исключения

`TypeError`

Возникает, если запрос не передан, либо если режим запроса 'no-cors', либо если нет сервис-воркера, либо если уже существует запрос с таким идентификатором, либо запрос завершился с ошибкой.

`AbortError` `DOMException` (en-US)

Указывает на то, что запрос был прерван.

`NotAllowedError` `DOMException` (en-US)

Указывает на то, что пользователю не было предоставлено разрешение на фоновые запросы.

Примеры
-------

Следующие примеры показывают, как использовать `fetch()`, чтобы создать `BackgroundFetchRegistration`. При активном `сервис-воркере`, используйте свойство `ServiceWorkerRegistration.backgroundFetch` (en-US) для доступа к объекту `BackgroundFetchManager` и вызовите его метод `fetch()`.

```js
navigator.serviceWorker.ready.then(async (swReg) => {
  const bgFetch = await swReg.backgroundFetch.fetch(
    "my-fetch",
    ["/ep-5.mp3", "ep-5-artwork.jpg"],
    {
      title: "Episode 5: Interesting things.",
      icons: [
        {
          sizes: "300x300",
          src: "/ep-5-icon.png",
          type: "image/png",
        },
      ],
      downloadTotal: 60 \* 1024 \* 1024,
    },
  );
});
```

Спецификации
------------

| Specification |
| --- |
| Background Fetch # background-fetch-manager-fetch |

Совместимость с браузерами
--------------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


BackgroundFetchManager.get() - Интерфейсы веб API

BackgroundFetchManager.get()
============================

Limited availability
--------------------

This feature is not Baseline because it does not work in some of the most widely-used browsers.

* Learn more
* See full compatibility
* Report feedback
Метод **`get()`** интерфейса `BackgroundFetchManager` возвращает `Promise`, результатом обработки которого будет объект `BackgroundFetchRegistration`, связанный с переданным `id`, или `undefined`, если идентификатор не найден.

Синтаксис
---------

```js
get(id);
```

### Параметры

`id`

Идентификатор `backgroundFetchRegistration`, определяемый при вызове `fetch()`.

### Возвращаемое значение

`Promise`, результатом обработки которого будет объект `BackgroundFetchRegistration` или `undefined`.

Примеры
-------

Следующие примеры показывают, как использовать `get()` для получения `BackgroundFetchRegistration`. При активном `сервис-воркере` используйте `ServiceWorkerRegistration.backgroundFetch` (en-US) для доступа к объекту `BackgroundFetchManager` и вызовите его метод `get()`.

```js
navigator.serviceWorker.ready.then(async (swReg) => {
  const bgFetch = await swReg.backgroundFetch.get('my-fetch');
});
my code block
```

Спецификации
------------

| Specification |
| --- |
| Background Fetch # background-fetch-manager-get |

Совместимость с браузерами
--------------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


BackgroundFetchManager.getIds() - Интерфейсы веб API

BackgroundFetchManager.getIds()
===============================

Limited availability
--------------------

This feature is not Baseline because it does not work in some of the most widely-used browsers.

* Learn more
* See full compatibility
* Report feedback
Метод **`getIds()`** интерфейса `BackgroundFetchManager` возвращает идентификаторы всех зарегистрированных фоновых запросов.

Синтаксис
---------

```js
getIds();
```

### Параметры

Отсутствуют.

### Возвращаемое значение

`Promise`, результатом обработки которого будет `массив` `строк`.

### Исключения

Отсутствуют.

Примеры
-------

Следующие примеры показывают, как получить идентификаторы всех зарегистрированных фоновых запросов. При активном `сервис-воркере` используйте свойство `ServiceWorkerRegistration.backgroundFetch` (en-US) для доступа к объекту `BackgroundFetchManager` и вызовите его метод `getIds()`.

```js
navigator.serviceWorker.ready.then(async (swReg) => {
  const ids = await swReg.backgroundFetch.getIds();
});
```

Спецификации
------------

| Specification |
| --- |
| Background Fetch # background-fetch-manager-get-ids |

Совместимость с браузерами
--------------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


Использование Fetch - Интерфейсы веб API

Использование Fetch
===================

Fetch API предоставляет интерфейс JavaScript для работы с запросами и ответами HTTP. Он также предоставляет глобальный метод `fetch()` (en-US), который позволяет легко и логично получать ресурсы по сети асинхронно.

Подобная функциональность ранее достигалась с помощью `XMLHttpRequest`. Fetch представляет собой лучшую альтернативу, которая может быть легко использована другими технологиями, такими как `Service Workers` (en-US). Fetch также обеспечивает единое логическое место для определения других связанных с HTTP понятий, такие как CORS и расширения для HTTP.

Обратите внимание, `fetch` спецификация отличается от `jQuery.ajax()` в основном в двух пунктах:

* Promise возвращаемый вызовом `fetch()` **не перейдёт в состояние "отклонено" из-за ответа HTTP, который считается ошибкой**, даже если ответ HTTP 404 или 500. Вместо этого, он будет выполнен нормально (с значением false в статусе `ok` ) и будет отклонён только при сбое сети или если что-то помешало запросу выполниться.
* По умолчанию, `fetch` **не будет отправлять или получать cookie файлы** с сервера, в результате чего запросы будут осуществляться без проверки подлинности, что приведёт к неаутентифицированным запросам, если сайт полагается на проверку пользовательской сессии (для отправки cookie файлов в аргументе init options должно быть задано значение свойства *credentials* отличное от значения по умолчанию `omit`).

**Примечание:** 25 августа 2017 г. в спецификации изменилось значение по умолчанию свойства *credentials* на `same-origin`. Firefox применяет это изменение с версии 61.0b13.

Базовый запрос на получение данных действительно прост в настройке. Взгляните на следующий код:
```

fetch('http://example.com/movies.json')
  .then((response) => {
    return response.json();
  })
  .then((data) => {
    console.log(data);
  });
```

Здесь мы забираем JSON файл по сети и выводим его содержимое в консоль. Самый простой способ использования `fetch()` заключается в вызове этой функции с одним аргументом — строкой, содержащей путь к ресурсу, который вы хотите получить — которая возвращает promise, содержащее ответ (объект `Response`).

Конечно, это просто HTTP-ответ, а не фактический JSON. Чтобы извлечь содержимое тела JSON из ответа, мы используем `json()` (en-US) метод (определён миксином `Body`, который реализован в объектах `Request` и `Response`.)

**Примечание:** Миксин Body имеет подобные методы для извлечения других типов контента; см. раздел Тело.

Fetch-запросы контролируются посредством директивы `connect-src` (Content Security Policy (en-US)), а не директивой извлекаемых ресурсов.

### Установка параметров запроса

Метод `fetch()` может принимать второй параметр - объект `init`, который позволяет вам контролировать различные настройки:

```js
// Пример отправки POST запроса:
async function postData(url = "", data = {}) {
  // Default options are marked with \*
  const response = await fetch(url, {
    method: "POST", // \*GET, POST, PUT, DELETE, etc.
    mode: "cors", // no-cors, \*cors, same-origin
    cache: "no-cache", // \*default, no-cache, reload, force-cache, only-if-cached
    credentials: "same-origin", // include, \*same-origin, omit
    headers: {
      "Content-Type": "application/json",
      // 'Content-Type': 'application/x-www-form-urlencoded',
    },
    redirect: "follow", // manual, \*follow, error
    referrerPolicy: "no-referrer", // no-referrer, \*client
    body: JSON.stringify(data), // body data type must match "Content-Type" header
  });
  return await response.json(); // parses JSON response into native JavaScript objects
}

postData("https://example.com/answer", { answer: 42 }).then((data) => {
  console.log(data); // JSON data parsed by `response.json()` call
});
```

С подробным описанием функции и полным списком параметров вы можете ознакомиться на странице `fetch()` (en-US).

### Отправка запроса с учётными данными

Чтобы браузеры могли отправлять запрос с учётными данными (даже для cross-origin запросов), добавьте `credentials: 'include'` в объект `init`, передаваемый вами в метод `fetch()`:

```js
fetch("https://example.com", {
  credentials: "include",
});
```

Если вы хотите отправлять запрос с учётными данными только если URL принадлежит одному источнику (origin) что и вызывающий его скрипт, добавьте credentials: 'same-origin'.

```js
// Вызывающий скрипт принадлежит источнику 'https://example.com'

fetch("https://example.com", {
  credentials: "same-origin",
});
```

Напротив, чтобы быть уверенным, что учётные данные не передаются с запросом, используйте credentials: 'omit':

```js
fetch("https://example.com", {
  credentials: "omit",
});
```

Отправка данных в формате JSON
------------------------------

При помощи `fetch()` (en-US) можно отправлять POST-запросы в формате JSON.

```js
const url = "https://example.com/profile";
const data = { username: "example" };

try {
  const response = await fetch(url, {
    method: "POST", // или 'PUT'
    body: JSON.stringify(data), // данные могут быть 'строкой' или {объектом}!
    headers: {
      "Content-Type": "application/json",
    },
  });
  const json = await response.json();
  console.log("Успех:", JSON.stringify(json));
} catch (error) {
  console.error("Ошибка:", error);
}
```

Загрузка файла на сервер
------------------------

На сервер можно загрузить файл, используя комбинацию HTML-элемента `<input type="file" />`, `FormData()` и `fetch()`.

```js
const formData = new FormData();
const fileField = document.querySelector('input[type="file"]');

formData.append("username", "abc123");
formData.append("avatar", fileField.files[0]);

try {
  const response = await fetch("https://example.com/profile/avatar", {
    method: "PUT",
    body: formData,
  });
  const result = await response.json();
  console.log("Успех:", JSON.stringify(result));
} catch (error) {
  console.error("Ошибка:", error);
}
```

Загрузка нескольких файлов на сервер
------------------------------------

На сервер можно загрузить несколько файлов, используя комбинацию HTML-элемента `<input type="file" multiple />`, `FormData()` и `fetch()`.

```js
const formData = new FormData();
const photos = document.querySelector('input[type="file"][multiple]');

formData.append("title", "Мой отпуск в Вегасе");
for (let i = 0; i < photos.files.length; i++) {
  formData.append("photos", photos.files[i]);
}

try {
  const response = await fetch("https://example.com/posts", {
    method: "POST",
    body: formData,
  });
  const result = await response.json();
  console.log("Успех:", JSON.stringify(result));
} catch (error) {
  console.error("Ошибка:", error);
}
```

Обработка текстового файла построчно
------------------------------------

Фрагменты данных, получаемые из ответа, не разбиваются на строки автоматически (по крайней мере с достаточной точностью) и представляют собой не строки, а объекты `Uint8Array` (en-US). Если вы хотите загрузить текстовый файл и обрабатывать его по мере загрузки построчно, то на вас самих ложится груз ответственности за обработку всех упомянутых моментов. Как пример, далее представлен один из способов подобной обработки с помощью создания построчного итератора (для простоты приняты следующие допущения: текст приходит в кодировке UTF-8 и ошибки получения не обрабатываются).

```js
async function\* makeTextFileLineIterator(fileURL) {
  const utf8Decoder = new TextDecoder("utf-8");
  let response = await fetch(fileURL);
  let reader = response.body.getReader();
  let { value: chunk, done: readerDone } = await reader.read();
  chunk = chunk ? utf8Decoder.decode(chunk) : "";

  let re = /\n|\r|\r\n/gm;
  let startIndex = 0;
  let result;

  for (;;) {
    let result = re.exec(chunk);
    if (!result) {
      if (readerDone) {
        break;
      }
      let remainder = chunk.substr(startIndex);
      ({ value: chunk, done: readerDone } = await reader.read());
      chunk = remainder + (chunk ? utf8Decoder.decode(chunk) : "");
      startIndex = re.lastIndex = 0;
      continue;
    }
    yield chunk.substring(startIndex, result.index);
    startIndex = re.lastIndex;
  }
  if (startIndex < chunk.length) {
    //последняя строка не имеет символа перевода строки в конце
    yield chunk.substr(startIndex);
  }
}

for await (let line of makeTextFileLineIterator(urlOfFile)) {
  processLine(line);
}
```

Проверка успешности запроса
---------------------------

В методе `fetch()` (en-US) promise будет отклонён (reject) с `TypeError`, когда случится ошибка сети или не будет сконфигурирован CORS на стороне запрашиваемого сервера, хотя обычно это означает проблемы доступа или аналогичные — для примера, 404 не является сетевой ошибкой. Для достоверной проверки успешности fetch() будет включать проверку того, что promise успешен (resolved), затем проверку того, что значение свойства `Response.ok` (en-US) является true. Код будет выглядеть примерно так:

```js
try {
  const response = await fetch("flowers.jpg");
  if (!response.ok) {
    throw new Error("Ответ сети был не ok.");
  }
  const myBlob = await response.blob();
  const objectURL = URL.createObjectURL(myBlob);
  myImage.src = objectURL;
} catch (error) {
  console.log("Возникла проблема с вашим fetch запросом: ", error.message);
}
```

Составление своего объекта запроса
----------------------------------

Вместо передачи пути ресурса, который вы хотите запросить вызовом fetch(), вы можете создать объект запроса, используя конструктор `Request()` (en-US), и передать его в fetch() аргументом:

```js
const myHeaders = new Headers();

const myInit = {
  method: "GET",
  headers: myHeaders,
  mode: "cors",
  cache: "default",
};

const myRequest = new Request("flowers.jpg", myInit);
const response = await fetch(myRequest);
const myBlob = await response.blob();
const objectURL = URL.createObjectURL(myBlob);
myImage.src = objectURL;
```

Конструктор Request() принимает точно такие же параметры, как и метод fetch(). Вы даже можете передать существующий объект запроса для создания его копии:

```js
const anotherRequest = new Request(myRequest, myInit);
```

Довольно удобно, когда тела запроса и ответа используются единожды (прим.пер.: "are one use only"). Создание копии как показано позволяет вам использовать запрос/ответ повторно, при изменении опций init, при желании. Копия должна быть сделана до прочтения тела, а чтение тела в копии также пометит его прочитанным в исходном запросе.

Примечание: Также есть метод `clone()` (en-US), создающий копии. Оба метода создания копии прекратят работу с ошибкой если тело оригинального запроса или ответа уже было прочитано, но чтение тела клонированного ответа или запроса не приведёт к маркировке оригинального.

Заголовки
---------

Интерфейс `Headers` (en-US) позволяет вам создать ваш собственный объект заголовков через конструктор `Headers()` (en-US). Объект заголовков - простая мультикарта имён-значений:

```js
const content = "Hello World";
const myHeaders = new Headers();
myHeaders.append("Content-Type", "text/plain");
myHeaders.append("Content-Length", content.length.toString());
myHeaders.append("X-Custom-Header", "ProcessThisImmediately");
```

То же может быть достигнуто путём передачи массива массивов или литерального объекта конструктору:

```js
const myHeaders = new Headers({
  "Content-Type": "text/plain",
  "Content-Length": content.length.toString(),
  "X-Custom-Header": "ProcessThisImmediately",
});
```

Содержимое может быть запрошено и извлечено:

```js
console.log(myHeaders.has("Content-Type")); // true
console.log(myHeaders.has("Set-Cookie")); // false
myHeaders.set("Content-Type", "text/html");
myHeaders.append("X-Custom-Header", "AnotherValue");

console.log(myHeaders.get("Content-Length")); // 11
console.log(myHeaders.get("X-Custom-Header")); // ["ProcessThisImmediately", "AnotherValue"]

myHeaders.delete("X-Custom-Header");
console.log(myHeaders.get("X-Custom-Header")); // [ ]
```

Некоторые из этих операций могут быть использованы только в `ServiceWorkers` (en-US), но они предоставляют более удобный API для манипуляции заголовками.

Все методы Headers выбрасывают TypeError, если имя используемого заголовка не является валидным именем HTTP Header. Операции мутации выбросят TypeError если есть защита от мутации (смотрите ниже) (прим.пер.: "if there is an immutable guard"). В противном случае они прерываются молча. Например:

```js
const myResponse = Response.error();
try {
  myResponse.headers.set("Origin", "http://mybank.com");
} catch (e) {
  console.log("Не могу притвориться банком!");
}
```

Хорошим вариантом использования заголовков является проверка корректности типа контента перед его обработкой. Например:

```js
try {
  const response = await fetch(myRequest);
  const contentType = response.headers.get("content-type");
  if (!contentType || !contentType.includes("application/json")) {
    throw new TypeError("Ой, мы не получили JSON!");
  }
  const json = await response.json();
  /\_ Дальнейшая обработка JSON \_/;
} catch (error) {
  console.log(error);
}
```

### Защита

С тех пор как заголовки могут передаваться в запросе, приниматься в ответе и имеют различные ограничения в отношении того, какая информация может и должна быть изменена, заголовки имеют свойство guard. Это не распространяется на Web, но влияет на то, какие операции мутации доступны для объекта заголовков.

Возможные значения:

none: по умолчанию.request: защита объекта заголовков, полученного по запросу (`Request.headers` (en-US)).request-no-cors: защита объекта заголовков, полученного по запросу созданного с `Request.mode` no-cors.response: защита Headers полученных от ответа (`Response.headers` (en-US)).immutable: в основном, используется в ServiceWorkers; делает объект заголовков read-only.

Примечание: вы не можете добавить или установить request защищаемые Headers' заголовок Content-Length. Аналогично, вставка Set-Cookie в заголовок ответа недопустимо: ServiceWorkers не допускают установки cookies через синтезированные ответы.

Объекты ответа

Как вы видели выше, экземпляр `Response` будет возвращён когда fetch() промис будет исполнен.

Свойства объекта-ответа которые чаще всего используются:

`Response.status` (en-US) — Целочисленное (по умолчанию 200) содержит код статуса ответа.`Response.statusText` (en-US) — Строка (по умолчанию"OK"), которая соответствует HTTP коду статуса.`Response.ok` (en-US) — как сказано ранее, это короткое свойство для упрощения проверки на то что статус ответа находится где-то между 200-299 включительно. Это свойство типа `Boolean` (en-US).

Они так же могут быть созданы с помощью JavaScript, но реальная польза от этого есть только при использовании `сервис-воркеров` (en-US), когда вы предоставляете собственный ответ на запрос с помощью метода `respondWith()` (en-US):

```js
const myBody = new Blob();

addEventListener("fetch", function (event) {
  // ServiceWorker перехватывает fetch
  event.respondWith(
    new Response(myBody, {
      headers: { "Content-Type": "text/plain" },
    }),
  );
});
```

Конструктор `Response()` принимает два необязательных аргумента — тело для ответа и объект init (аналогичный тому, который принимает `Request()` (en-US))

Примечание: Метод `error()` (en-US) просто возвращает ответ об ошибке. Аналогично, `redirect()` (en-US) возвращает ответ, приводящий к перенаправлению на указанный URL. Они также относятся только к Service Workers.

Тело
----

Запрос и ответ могут содержать данные тела. Тело является экземпляром любого из следующих типов:

`ArrayBuffer``ArrayBufferView` (en-US) (Uint8Array и подобные)`Blob`/Filestring`URLSearchParams``FormData`
`Body` примесь определяет следующие методы для извлечения тела (реализованы как для `Request` так и для `Response`). Все они возвращают promise, который в конечном итоге исполняется и выводит содержимое.

`arrayBuffer()` (en-US)`blob()` (en-US)`json()` (en-US)`text()` (en-US)`formData()` (en-US)
Это делает использование нетекстовых данных более лёгким, чем при XMR.

В запросе можно установить параметры для отправки тела запроса:

```js
const form = new FormData(document.getElementById("login-form"));
fetch("/login", {
  method: "POST",
  body: form,
});
```

Параметры request и response (and by extension the fetch() function), по возможности возвращают корректные типы данных. Параметр request также автоматически установит Content-Type в заголовок, если он не был установлен из словаря.

Функция обнаружения
-------------------

Поддержка Fetch API может быть обнаружена путём проверки наличия `Headers` (en-US), `Request`, `Response` или `fetch()` (en-US) в области видимости `Window` или `Worker`. Для примера:

```js
if (window.fetch) {
  // запустить мой fetch запрос здесь
} else {
  // сделать что-то с XMLHttpRequest?
}
```

Смотрите также
--------------

* ServiceWorker API
* HTTP CORS
* HTTP
* Полифил Fetch
* Примеры работы с Fetch на GitHub


Cross-global fetch usage - Интерфейсы веб API

Cross-global fetch usage
========================

Эта статья объясняет крайний случай, который случается с fetch (и потенциально с другими API, предоставляющими такой же способ получения данных). Когда cross-origin fetch, включающий относительный URL, инициируется из `<iframe>` (en-US), относительный URL может использовать текущий глобальный location вместо того что задаётся в iframe.

Крайний случай
--------------

Многие сайты никогда не столкнутся с таким поведением. Чтобы увидеть его:

* Вам понадобится same-origin iframe
* Этот same-origin iframe должен располагаться с другим base URL
* Вы должны использовать функцию fetch cross-global, т. е. `frame.contentWindow.fetch()`
* Переданный в fetch URL должен быть относительным
Проблема
--------

В прошлом мы разрешали относительный URL адрес вместо текущего глобального, для примера:

```js
let absolute = new URL(relative, window.location.href);
```

Это не проблема как таковая. Просто разные API, демонстрирующие такое поведение, делали его несовместимым с поведением, определённым в спецификации, что может привести к проблемам в дальнейшем.

Решение
-------

В Firefox 60 и далее, Mozilla сопоставляет относительный URL с глобальным, которой принадлежит используемой функции `fetch()` (смотри Firefox bug 1432272). Таким образом в случае описанном выше, он разрешается в зависимости от расположения iframe:

```js
let absolute = new URL(relative, frame.contentWindow.location.href);
```

Ведётся много дискуссий о том, как привести новые спецификации в соответствие с этим изменением поведения, для того чтобы уменьшить возможные проблемы в будущем.


HTMLDialogElement.open - Интерфейсы веб API

HTMLDialogElement.open
======================

Baseline 2022
-------------

Newly availableSince March 2022, this feature works across the latest devices and browser versions. This feature might not work in older devices or browsers.

* Learn more
* See full compatibility
* Report feedback
**Экспериментальная возможность:** **Это экспериментальная технология**
Так как спецификация этой технологии ещё не стабилизировалась, смотрите таблицу совместимости по поводу использования в различных браузерах. Также заметьте, что синтаксис и поведение экспериментальной технологии может измениться в будущих версиях браузеров, вслед за изменениями спецификации.

**`open`** - свойство интерфейса взаимодействия `HTMLDialogElement`, является `Boolean` (en-US) значением и отражает HTML атрибут `open` этого элемента, указывающий, доступен ли `<dialog>` для взаимодействия.

Синтаксис
---------
```

dialogInstance.open = true;
var myOpenValue = dialogInstance.open;
```

### Значение

`Boolean` (en-US) значение отражает состояние HTML атрибута `open`. `true` значит, что значение установлено и диалоговое окно показывается в настоящий момент. `false` указывает, что значение не установлено и диалоговое окно не показывается.

Свойство доступно только для чтения — значение можно установить программно методы show и hide элемента `<dialog>`.

Примеры
-------

Примеры ниже показывают простую кнопку, которая по нажатию открывает `<dialog>`, содержащий `<form>`, используя `showModal()` метод. Вы можете нажать кнопку *Отмена* для закрытия (используя `HTMLDialogElement.close()` (en-US) метод) или принять `<form>`, нажав на кнопку *Принять*.

```html
<!-- Simple pop-up dialog box, containing a form -->
<dialog id="favDialog">
  <form method="dialog">
    <section>
      <p>
        <label for="favAnimal">Favorite animal:</label>
        <select id="favAnimal" name="favAnimal">
          <option></option>
          <option>Brine shrimp</option>
          <option>Red panda</option>
          <option>Spider monkey</option>
        </select>
      </p>
    </section>
    <menu>
      <button id="cancel" type="reset">Cancel</button>
      <button type="submit">Confirm</button>
    </menu>
  </form>
</dialog>

<menu>
  <button id="updateDetails">Update details</button>
</menu>

<script>
 (function () {
 var updateButton = document.getElementById("updateDetails");
 var cancelButton = document.getElementById("cancel");
 var dialog = document.getElementById("favDialog");
 dialog.returnValue = "favAnimal";

 function openCheck(dialog) {
 if (dialog.open) {
 console.log("Dialog open");
 } else {
 console.log("Dialog closed");
 }
 }

 // Кнопка обновления открывает диалоговое окно
 updateButton.addEventListener("click", function () {
 dialog.showModal();
 openCheck(dialog);
 });

 // Кнопка отмены закрывает диалоговое окно
 cancelButton.addEventListener("click", function () {
 dialog.close("animalNotChosen");
 openCheck(dialog);
 });
 })();
</script>
```

**Примечание:** вы можете найти данный пример на htmldialogelement-basic (see it live also).

Спецификации
------------

| Specification |
| --- |
| HTML Standard # dom-dialog-open |

Совместимость с браузерами
--------------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

Смотрите также
--------------

* HTML-элемент, использующий данный интерфейс взаимодействия: `<dialog>`.


GlobalEventHandlers.onclose - Интерфейсы веб API

GlobalEventHandlers.onclose
===========================

Baseline 2022
-------------

Newly availableSince March 2022, this feature works across the latest devices and browser versions. This feature might not work in older devices or browsers.

* Learn more
* See full compatibility
* Report feedback
Обработчик события для событий закрытия, отправляется в окно. (Не доступен в Firefox 2 или Safari)

Синтаксис
---------
```

window.onclose = funcRef;
```

### Параметры

* `funcRef` является ссылкой на функцию.
Пример
------

```js
window.onclose = resetThatServerThing;
```

Спецификация
------------

| Specification |
| --- |
| HTML Standard # event-close |

Совместимость с браузерами
--------------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


Animation.cancel() - Интерфейсы веб API

Animation.cancel()
==================

Baseline 2022
-------------

Newly availableSince September 2022, this feature works across the latest devices and browser versions. This feature might not work in older devices or browsers.

* Learn more
* See full compatibility
* Report feedback
**Экспериментальная возможность:** **Это экспериментальная технология**
Так как спецификация этой технологии ещё не стабилизировалась, смотрите таблицу совместимости по поводу использования в различных браузерах. Также заметьте, что синтаксис и поведение экспериментальной технологии может измениться в будущих версиях браузеров, вслед за изменениями спецификации.

Метод **`cancel()`** API Web Animation интерфейса `Animation` очищает все `KeyframeEffect` (en-US) вызванной этой анимацией и прекращает его воспроизведение.

**Примечание:** Когда анимация отменена, её `startTime` и `currentTime` (en-US) устанавливаются в `null`.

Syntax
------
```

Animation.cancel();
```

### Parameters

None.

### Return value

None.

### Exceptions

Этот метод не выбрасывает напрямую исключения; однако, если `playState` (en-US) анимации во время отмены ничего кроме `"idle"`, current finished promise (en-US) отклоняется с помощью `DOMException` (en-US) названным `AbortError`.

Спецификации
------------

| Specification |
| --- |
| Web Animations # dom-animation-cancel |

Совместимость с браузерами
--------------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* Web Animations API
* `KeyframeEffect` (en-US)
* `Animation`
* `Animation.playState` (en-US)
* `Animation.finished` (en-US) returns the promise this action will reject if the animation's `playState` is not `"idle"`.


Window.mozAnimationStartTime - Интерфейсы веб API

Window.mozAnimationStartTime
============================

Baseline 2022
-------------

Newly availableSince September 2022, this feature works across the latest devices and browser versions. This feature might not work in older devices or browsers.

* Learn more
* See full compatibility
* Report feedback
**Не стандартно:** Эта возможность не является стандартной и стандартизировать её пока никто не собирается. Не используйте её на сайтах, смотрящих во внешний мир: она будет работать не у всех пользователей. Также могут присутствовать большие несовместимости между реализациями и её поведение может в будущем измениться.

### Summary

Возвращает время в миллисекундах с начала эпохи UNIX, начиная с которого анимации, начавшиеся в определённый момент, должны быть сочтены уже начавшимися. Это значение должно быть использовано вместо, например, `Date.now()`, потому что оно будет тем же самым для анимаций, начавшихся в этом окне в течение этого интервала, позволяя им синхронизироваться между собой.

Это также позволяет анимациям JavaScript оставаться синхронизированными с CSS переходами и SMIL анимациями, запущенными в течение того же интервала обновления.

### Syntax
```

time = window.mozAnimationStartTime;
```

### Parameters

* *`time`* это время в миллисекундах с начала эпохи UNIX, начиная с которого анимации для текущего окна принимаются уже начавшимися.
### Specification

Not part of specification.

Совместимость с браузерами
--------------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

### See also

* `window.mozRequestAnimationFrame()` (en-US)
* `window.onmozbeforepaint`


XMLHttpRequest.responseXML - Интерфейсы веб API

XMLHttpRequest.responseXML
==========================

`Свойство XMLHttpRequest.responseXML` это доступное только для чтения значение, которое содержит `Document` содержащий HTML или XML полученный запросом, или `null` в случае, если запрос не был успешен, ещё не был отправлен или полученные данные не могут быть корректно обработаны как XML или HTML. Ответ обрабатывается так, как если бы это был `"text/xml"`. В случае, если `responseType` установлен как `"document"` и запрос был осуществлён асинхронно, ответ обрабатывается как `"text/html"`. `responseXML` содержит `null` для любых других типов данных так же, как и для `data:` URLs.

**Примечание:** Название `responseXML` это наследие истории этого свойства, на самом деле оно работает как для HTML, так и для XML.

Если сервер не определяет заголовок `Content-Type` как `"text/xml"` или `"application/xml"`, вы в любом случае можете использовать `XMLHttpRequest.overrideMimeType()` (en-US) чтобы заставить `XMLHttpRequest` обрабатывать ответ как XML.

Синтаксис
---------
```

var data = XMLHttpRequest.responseXML;
```

### Значение

`Document` содержащий древовидный результат обработки XML или HTML, полученных с использованием `XMLHttpRequest`, или `null`, если данные не были получены или содержат другой тип данных.

### Исключения

`InvalidStateError`

`responseType` не является `"document"` или пустой строкой (каждый из которых указывает, что принятые данные это XML или HTML).

Пример
------

```js
var xhr = new XMLHttpRequest();
xhr.open("GET", "/server", true);

// Значение responseType, если указано, должно быть пустой строкой или "document"
xhr.responseType = "document";

// overrideMimeType() может быть использован, чтобы заставить ответ обрабатываться как XML
xhr.overrideMimeType("text/xml");

xhr.onload = function () {
  if (xhr.readyState === xhr.DONE) {
    if (xhr.status === 200) {
      console.log(xhr.response);
      console.log(xhr.responseXML);
    }
  }
};

xhr.send(null);
```

Спецификации
------------

| Specification |
| --- |
| XMLHttpRequest Standard # the-responsexml-attribute |

Совместимость с браузерами
--------------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

Смотрите также
--------------

* `XMLHttpRequest`
* `XMLHttpRequest.response`
* `XMLHttpRequest.responseType`


XMLHttpRequest.response - Интерфейсы веб API

XMLHttpRequest.response
=======================

Свойство `XMLHttpRequest` **`response`** возвращает содержимое тела ответа в виде `ArrayBuffer`, `Blob`, `Document`, `JavaScript Object` или `DOMString` в зависимости от значения свойства `responseType`.

Синтаксис
---------
```

var body = XMLHttpRequest.response;
```

### Value

Соответствующий объект, основанный на значении `responseType`. Вы можете попытаться запросить данные в определённом формате, установив значение `responseType` после вызова `open()` для инициализации запроса, но перед вызовом `send()` для отправки запроса на сервер.

Значение равно `null`, если запрос ещё не завершён или был неудачным, за исключением того, что при чтении текстовых данных с использованием `responseType "text"` или пустой строки (`""`), ответ может содержать ответ до тех пор, пока запрос все ещё находится в состоянии `LOADING readyState (3)`.

Типы ответов описаны ниже.

| Значение | Описание |
| --- | --- |
| `""` | Пустая строка `responseType` обрабатывается так же, как `"text"`, тип по умолчанию (следовательно, как `DOMString`.) |
| `"arraybuffer"` | `response` в JavaScript `ArrayBuffer` содержит двоичные данные. |
| `"blob"` | `response` в `Blob` object содержит двоичные данные. |
| `"document"` | `response` является HTML `Document` или XML `XMLDocument`, в зависимости от ситуации, основанный на MIME-типе полученных данных. См. HTML in XMLHttpRequest (en-US) , чтобы узнать больше об использовании XHR для извлечения содержимого HTML. |
| `"json"` | `response` является JavaScript object, созданный путём анализа содержимого полученных данных как JSON. |
| `"text"` | `response` является текстом в `DOMString` object. |
| `"moz-chunked-arraybuffer"` | Похож на `"arraybuffer"`, но данные принимаются в потоке. При использовании этого типа ответа значение в `response` доступно только в обработчике для события `progress` (en-US) и содержит только данные, полученные с момента последнего события `progress`, а не совокупные данные, полученные с момента отправки запроса.Доступ к `response` во время события `progress` возвращает полученные данные. За пределами обработчика событий `progress` значение `response` всегда равно `null`. |
| `"ms-stream"` | `response` является частью потоковой загрузки; этот тип ответа разрешён только для запросов на загрузку и поддерживается только Internet Explorer. |

Пример
------

В этом примере представлена функция `load()`, которая загружает и обрабатывает страницу с сервера. Он работает путём создания объекта `XMLHttpRequest` и создания обработчика события с событием `readystatechange`, чтобы при изменении `readyState` на `DONE (4)` `response` получался и передавался в колбэк-функцию, предоставляемую `load()`.

Содержимое обрабатывается как необработанные текстовые данные (поскольку здесь ничто не переопределяет `responseType` по умолчанию).

```js
var url = "somePage.html"; //A local page

function load(url, callback) {
  var xhr = new XMLHttpRequest();

  xhr.onreadystatechange = function () {
    if (xhr.readyState === 4) {
      callback(xhr.response);
    }
  };

  xhr.open("GET", url, true);
  xhr.send("");
}
```

Спецификации
------------

| Specification |
| --- |
| XMLHttpRequest Standard # the-response-attribute |

Совместимость с браузерами
--------------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

Смотрите также
--------------

* Using XMLHttpRequest
* Getting text and HTML/XML data: `XMLHttpRequest.responseText` and `XMLHttpRequest.responseXML`


XMLHttpRequest.statusText - Интерфейсы веб API

XMLHttpRequest.statusText
=========================

Свойство **`XMLHttpRequest.statusText`**, доступное только для чтения, возвращает строку `DOMString`, содержащую сообщение о состоянии ответа, возвращаемое HTTP-сервером. В отличие от `XMLHTTPRequest.status`, который указывает числовой код состояния, это свойство содержит текст состояния ответа, например «OK» или «Not Found». Если запрос `readyState` находится в состоянии `UNSENT` или `OPENED`, значением `statusText` будет пустая строка.

Если в ответе сервера явно не указан текст состояния, для `statusText` будет принято значение по умолчанию «ОК».

Пример
------

```js
var xhr = new XMLHttpRequest();
console.log("0 UNSENT", xhr.statusText);

xhr.open("GET", "/server", true);
console.log("1 OPENED", xhr.statusText);

xhr.onprogress = function () {
  console.log("3 LOADING", xhr.statusText);
};

xhr.onload = function () {
  console.log("4 DONE", xhr.statusText);
};

xhr.send(null);

/\*\*
 \* Outputs the following:
 \*
 \* 0 UNSENT
 \* 1 OPENED
 \* 3 LOADING OK
 \* 4 DONE OK
 \*/
```

Спецификации
------------

| Specification |
| --- |
| XMLHttpRequest Standard # the-statustext-attribute |

Совместимость с браузерами
--------------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

Смотрите также
--------------

* Список HTTP response codes
* HTTP


XMLHttpRequest.onreadystatechange - Интерфейсы веб API

XMLHttpRequest.onreadystatechange
=================================

`Обработчик события (EventHandler)` (en-US), который вызывается всякий раз, когда изменяется состояние свойства `readyState`. Свойство **`XMLHttpRequest.onreadystatechange`** содержит обработчик события, вызываемый когда происходит событие `readystatechange (en-US)`, всякий раз когда свойство `readyState` запроса `XMLHttpRequest` изменяется. Колбэк-функция запускается из потока пользовательского интерфейса.

**Предупреждение:** **Внимание:** Не должно использоваться при синхронных запросах и из исходного кода (native code).

Событие `readystatechange` не произойдёт если запрос `XMLHttpRequest` отменён методом abort().

Синтаксис
---------
```

XMLHttpRequest.onreadystatechange = callback;
```

### Значение

* `callback` - это функция, которая будет вызываться при изменении свойства `readyState`.
Пример
------

```js
var xhr = new XMLHttpRequest(),
  method = "GET",
  url = "https://developer.mozilla.org/";

xhr.open(method, url, true);
xhr.onreadystatechange = function () {
  if (xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) {
    console.log(xhr.responseText);
  }
};
xhr.send();
```

Спецификации
------------

| Specification |
| --- |
| XMLHttpRequest Standard # event-xhr-readystatechange |
| XMLHttpRequest Standard # handler-xhr-onreadystatechange |

Совместимость с браузерами
--------------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


XMLHttpRequest.timeout - Интерфейсы веб API

XMLHttpRequest.timeout
======================

Свойство **`XMLHttpRequest.timeout`** определяет количество миллисекунд, которое запрос будет выполняться, до того, как будет автоматически прерван. Имеет размер `unsigned long.` Значение по умолчанию - 0, определяет, что таймаута нет. Таймаут не должен быть использован в синхронных запросах XMLHttpRequests в среде документа (en-US), или будет вызвано исключение `InvalidAccessError`. Когда случается таймаут - вызывается событие timeout (en-US).

**Примечание:** вы не можете использовать таймаут для синхронных запросов с окном - владельцем. Использование таймаута с асинхронными запросами

В Internet Explorer, свойство timeout может быть установлено только после вызова метода open() и до вызова метода send().

Пример
------

```js
var xhr = new XMLHttpRequest();
xhr.open("GET", "/server", true);

xhr.timeout = 2000; // time in milliseconds

xhr.onload = function () {
  // Запрос завершён. Здесь можно выполнить обработку.
};

xhr.ontimeout = function (e) {
  // Таймаут. Здесь можно выполнить что-нибудь..
};

xhr.send(null);
```

Спецификации
------------

| Specification |
| --- |
| XMLHttpRequest Standard # the-timeout-attribute |


XMLHttpRequest.status - Интерфейсы веб API

XMLHttpRequest.status
=====================

Доступное только для чтения свойство **`XMLHttpRequest.status`**, возвращает числовой код состояния HTTP ответа `XMLHttpRequest`.

До завершения запроса значение `status` равно 0. Браузеры также сообщают о состоянии 0 в случае ошибок `XMLHttpRequest`.

Пример
------

```js
var xhr = new XMLHttpRequest();
console.log("UNSENT: ", xhr.status);

xhr.open("GET", "/server");
console.log("OPENED: ", xhr.status);

xhr.onprogress = function () {
  console.log("LOADING: ", xhr.status);
};

xhr.onload = function () {
  console.log("DONE: ", xhr.status);
};

xhr.send();

/\*\*
 \* Outputs the following:
 \*
 \* UNSENT: 0
 \* OPENED: 0
 \* LOADING: 200
 \* DONE: 200
 \*/
```

Спецификации
------------

| Specification |
| --- |
| XMLHttpRequest Standard # the-status-attribute |

Совместимость с браузерами
--------------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

Смотрите также
--------------

* Список HTTP response codes
* HTTP


XMLHttpRequest.readyState - Интерфейсы веб API

XMLHttpRequest.readyState
=========================

**Свойство XMLHttpRequest.readyState** возвращает текущее состояние объекта XMLHttpRequest. Объект XHR может иметь следующие состояния:

| Значение | Состояние | Описание |
| --- | --- | --- |
| `0` | `UNSENT` | Объект был создан. Метод `open()` ещё не вызывался. |
| `1` | `OPENED` | `Метод open()` был вызван. |
| `2` | `HEADERS_RECEIVED` | `Метод send()` был вызван, доступны заголовки (headers) и статус. |
| `3` | `LOADING` | Загрузка; `responseText` содержит частичные данные. |
| `4` | `DONE` | Операция полностью завершена. |

UNSENT

Объект XMLHttpRequest был создан, но метод `open()` ещё не вызывался.

OPENED

Был вызван метод open(). На этом этапе методом setRequestHeader() могут быть установлены заголовки запроса (request headers), после чего для начала выполнения запроса может быть вызван метод send() .

HEADERS\_RECEIVED

Был вызван метод send() и получены заголовки ответа (response headers) .

LOADING

Получена часть ответа. Если `responseType` - это пустая строка или имеет значение "text", `responseText` будет содержать загруженную порцию текста ответа.

DONE

Операция доставки данных завершена. Это может означать как то, что передача данных полностью завершена успешно, так и то, что произошла ошибка.

**Примечание:** Названия состояний отличаются в версиях Internet Explorer ранее 11. Вместо `UNSENT`, `OPENED`, `HEADERS_RECEIVED`, `LOADING` и `DONE`, используются названия `READYSTATE_UNINITIALIZED` (0), `READYSTATE_LOADING` (1), `READYSTATE_LOADED` (2), `READYSTATE_INTERACTIVE` (3) и `READYSTATE_COMPLETE` (4).

Пример
------

```js
var xhr = new XMLHttpRequest();
console.log("UNSENT", xhr.readyState); // readyState будет равно 0

xhr.open("GET", "/api", true);
console.log("OPENED", xhr.readyState); // readyState будет равно 1

xhr.onprogress = function () {
  console.log("LOADING", xhr.readyState); // readyState будет равно 3
};

xhr.onload = function () {
  console.log("DONE", xhr.readyState); // readyState будет равно 4
};

xhr.send(null);
```

Спецификации
------------

| Specification |
| --- |
| XMLHttpRequest Standard # states |

Совместимость с браузерами
--------------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


XMLHttpRequest.responseText - Интерфейсы веб API

XMLHttpRequest.responseText
===========================

Только для чтения `XMLHttpRequest` свойство **`responseText`** возвращает текст ответа от сервера на отправленный запрос.

Syntax
------
```

var resultText = XMLHttpRequest.responseText;
```

### Значение

Строка `DOMString` содержащая либо текстовые данные, полученные при использовании `XMLHttpRequest`, либо `null` в случае, когда вопрос возвратил ошибку, или же ещё не был отослан на сервер вызовом функции `send()`.

Во время выполнения асинхронных запросов, в значении `responseText` всегда находится текущее содержимое, полученное от сервера, даже если запрос ещё не завершён, и данные от сервера не получены полностью.

Понять, что ответ получен полностью, можно когда значение `readyState` становится `XMLHttpRequest.DONE` (`4`), а значение `status` становится 200 (`"OK"`).

### Исключения

`InvalidStateError`

Возникает, когда значению `XMLHttpRequest.responseType` не присвоена либо пустая строка, либо "text". Поскольку свойство `responseText` предназначено только для текстового содержимого, любое другое значение вызовет ошибку.

Пример
------

```js
var xhr = new XMLHttpRequest();
xhr.open("GET", "/server", true);

// responseType должно быть пустой строкой, либо "text"
xhr.responseType = "text";

xhr.onload = function () {
  if (xhr.readyState === xhr.DONE) {
    if (xhr.status === 200) {
      console.log(xhr.response);
      console.log(xhr.responseText);
    }
  }
};

xhr.send(null);
```

Спецификации
------------

| Specification |
| --- |
| XMLHttpRequest Standard # the-responsetext-attribute |

Совместимость с браузерами
--------------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


XMLHttpRequest.send() - Интерфейсы веб API

XMLHttpRequest.send()
=====================

Метод **`XMLHttpRequest.send()`** отправляет запрос. Если запрос асинхронный (каким он является по умолчанию), то возврат из данного метода происходит сразу после отправления запроса. Если запрос синхронный, то метод возвращает управление только после получения ответа. Метод `send()` принимает необязательные аргументы в тело запросов. Если метод запроса `GET` или `HEAD`, то аргументы игнорируются и тело запроса устанавливается в null.

Если заголовок `Accept` не был задан с помощью `setRequestHeader()`, будет отправлено значение `Accept` по умолчанию `*/*`.

Синтаксис
---------
```

XMLHttpRequest.send(body)
```

### Параметры

*body* Необязательный

Данные из параметра body оправляются в запросе через XHR. Это могут быть:

* `Document`, и в этом случае данные будут сериализованы перед отправкой.
* `BodyInit`, которые, согласно спецификации Fetch могут быть: `Blob`, `BufferSource`, `FormData`, `URLSearchParams`, `ReadableStream` (en-US), или объектом `USVString` (en-US).

Лучший способ передать двоичные данные (например при загрузке файлов) - это использование ArrayBufferView (en-US) или Blobs в сочетании с методом`send()`.

Если никакого значения не определено в качестве *body*, то будет использовано значение по умолчанию: `null`.

### Возвращаемое значение

`undefined`.

### Исключения

| Исключение | Описание |
| --- | --- |
| `InvalidStateError` | `send()` уже был вызван для запроса, и/или запрос завершён. |
| `NetworkError` | Тип запрошенного ресурса - Blob, но метод запроса не `GET`. |

Пример: GET
-----------
```

var xhr = new XMLHttpRequest();
xhr.open('GET', '/server', true);

xhr.onload = function () {
  // Запрос завершён. Здесь можно обрабатывать результат.
};

xhr.send(null);
// xhr.send('string');
// xhr.send(new Blob());
// xhr.send(new Int8Array());
// xhr.send({ form: 'data' });
// xhr.send(document);
```

Пример: POST
------------
```

var xhr = new XMLHttpRequest();
xhr.open("POST", '/server', true);

//Передаёт правильный заголовок в запросе
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");

xhr.onreadystatechange = function() {//Вызывает функцию при смене состояния.
    if(xhr.readyState == XMLHttpRequest.DONE && xhr.status == 200) {
        // Запрос завершён. Здесь можно обрабатывать результат.
    }
}
xhr.send("foo=bar&lorem=ipsum");
// xhr.send('string');
// xhr.send(new Blob());
// xhr.send(new Int8Array());
// xhr.send({ form: 'data' });
// xhr.send(document);
```

Спецификации
------------

| Specification |
| --- |
| XMLHttpRequest Standard # the-send()-method |

Совместимость с браузерами
--------------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

Смотрите также
--------------

* Использование XMLHttpRequest
* HTML in XMLHttpRequest (en-US)


XMLHttpRequest() - Интерфейсы веб API

XMLHttpRequest()
================

#### XMLHttpRequest

Конструктор **`XMLHttpRequest()`** создаёт новый объект `XMLHttpRequest`.

Для получения подробной информации о том, как использовать `XMLHttpRequest`, см. Использование XMLHttpRequest.

Синтаксис
---------
```

const request = new XMLHttpRequest();
```

### Параметры

Нет.

### Возвращаемое значение

Новый объект `XMLHttpRequest`. Этот объект должен быть подготовлен вызовом функции `open()` перед вызовом `send()` для отправки запроса на сервер.

Нестандартный синтаксис Firefox
-------------------------------

В Firefox 16 в конструктор добавлен нестандартный параметр, который позволяет включать анонимный режим (см. Firefox bug 692677). Установка флага `mozAnon` в значение `true` по сути напоминает конструктор `AnonXMLHttpRequest()`, описанный в более старых версиях спецификации XMLHttpRequest.
```

const request = new XMLHttpRequest(paramsDictionary);
```

### Параметры (нестандартные)

`objParameters`

Существует два флага, которые можно установить:

`mozAnon`

Boolean: Установка этого флага в значение `true` приведёт к тому, что браузер не будет раскрывать origin и учётные данные пользователя при получении ресурсов. Главным образом это означает, что файлы cookies не будут отправлены, если они не добавлены явно с использованием setRequestHeader.

`mozSystem`

Boolean: Установка этого флага в значение `true` позволяет устанавливать межсайтовые соединения не требуя подключения сервера с помощью CORS. *Требует установки флага `mozAnon: true`, т.к. это нельзя сочетать с отправкой файлов cookie или других учётных данных пользователя. Это работает только в привилегированных (проверенных) приложениях (Firefox bug 692677)); не работает на произвольных веб-страницах, загруженных в Firefox.*

Смотрите также
--------------

* Использование XMLHttpRequest
* HTML в XMLHttpRequest (en-US)


XMLHttpRequest.open() - Интерфейсы веб API

XMLHttpRequest.open()
=====================

Метод **XMLHttpRequest.open()** инициализирует новый запрос или повторно инициализирует уже созданный.

**Примечание:** Вызов этого метода для уже активного запроса (для которого уже был вызван `open()`) эквивалентно вызову `abort()`.

Синтаксис
---------
```

XMLHttpRequest.open(method, url[, async[, user[, password]]])
```

### Параметры

`method`

Для HTTP-запроса используются такие методы как "GET", "POST", "PUT", "DELETE", и т. д. Игнорируется для URL, отличных от HTTP(S)-запросов.

`url`

`DOMString` представляет URL для отправки запроса.

`async` Необязательный

Необязательный логический параметр со значением по умолчанию `true`, указывающим, выполнять ли операцию асинхронно или нет. Если это значение равно `false`, метод `send()` не возвращается, пока не будет получен ответ. Если `true`, уведомление о получении ответа осуществляется с помощью обработчика события. Должен быть `true`, если атрибут `multipart` равен `true`, иначе будет выброшено исключение.

**Примечание:** Синхронные запросы в основном потоке могут нарушить работу пользователя, их следует избегать. Фактически большинство браузеров полностью отказались от поддержки синхронных XHR в основном потоке. Синхронные запросы можно использовать в `Worker`.

`user` Необязательный

Опционально: имя пользователя, использующееся для аутентификации; по умолчанию имеет значение `null`.

`password` Необязательный

Опционально: пароль, использующийся для аутентификации; по умолчанию имеет значение `null`.

Спецификации
------------

| Specification |
| --- |
| XMLHttpRequest Standard # the-open()-method |

Совместимость с браузерами
--------------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

Смотрите также
--------------

* Использование XMLHttpRequest
* `setRequestHeader()`
* `send()`
* `abort()`


XMLHttpRequest.setRequestHeader() - Интерфейсы веб API

XMLHttpRequest.setRequestHeader()
=================================

Метод **XMLHttpRequest.setRequestHeader()** устанавливает значения HTTP заголовков. Метод `setRequestHeader()` следует вызывать только после `open()`, но до `send()`. Если метод вызывается несколько раз подряд, значения присоединяется к одному и тому же заголовку.

Если заголовок `Accept` не был установлен, то он будет передан в запросе со значением `*/*` когда будет вызван метод `send()`.

В целях безопасности, некоторые заголовки не могут быть установлены программно. Для более подробной информации, смотрите forbidden header names и forbidden response header names.

**Примечание:** Для ваших собственных полей, вы можете увидеть исключение "**not allowed by Access-Control-Allow-Headers in preflight response**", когда вы делаете кросс-доменный запрос. В этом случае, вам нужно установить заголовок "Access-Control-Allow-Headers" в ответе на стороне сервера.

Синтаксис
---------
```

XMLHttpRequest.setRequestHeader(header, value)
```

### Параметры

`header`

Имя устанавливаемого заголовка

`value`

Значение, которое будет установлено как тело заголовка

Спецификации
------------

| Specification |
| --- |
| XMLHttpRequest Standard # the-setrequestheader()-method |

Совместимость с браузерами
--------------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

Смотрите также
--------------

Использование XMLHttpRequest


XMLHttpRequest.responseType - Интерфейсы веб API

XMLHttpRequest.responseType
===========================

**`XMLHttpRequest.responseType`** Свойство является перечислимым значением, которое возвращает тип ответа. Он также позволяет автору изменять тип ответа. Если значение не задано, будет использовано значение по умолчанию **`text`**. Установка значения responseType в «document» игнорируется, если выполняется в рабочей среде. При настройке `responseType` на определённое значение автор должен убедиться, что сервер действительно отправляет ответ, совместимый с этим форматом. Если сервер возвращает данные, которые не совместимы с установленным `responseType`, значение `response` будет `null`. Кроме того, установка `responseType` для синхронных запросов вызовет исключение `InvalidAccessError`.

Поддерживаемые значения `responseType`:

| Value | Data type of `response` property |
| --- | --- |
| `""` | `DOMString` (this is the default value) |
| `"arraybuffer"` | `ArrayBuffer` |
| `"blob"` | `Blob` |
| `"document"` | `Document` |
| `"json"` | `JSON` |
| `"text"` | `DOMString` |
| `"moz-chunked-arraybuffer"`
Non-standard
 | Похоже на `"arraybuffer"`, но потоковое. Это означает, что значение в `response` доступно только при отправке `"progress"` события и содержит только данные, полученные с момента последнего `"progress"` события.При `response` обращении во время события `"progress"` он содержит строку с данными. В противном случае он возвращается `null`.Этот режим работает только в Firefox.. |
| "ms-stream"
Non-standard
 | Указывает, что ответ является частью потоковой загрузки. Он поддерживается только для запросов на загрузку. Этот режим доступен только в Internet Explorer. |

Спецификации
------------

| Specification |
| --- |
| XMLHttpRequest Standard # the-responsetype-attribute |

Совместимость с браузерами
--------------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.