Skip to content

Commit 8816aa6

Browse files
authored
Merge pull request #52 from sherbakov1/master
5-network/01-fetch-basics/article.md
2 parents b98ed4b + cb4e1c4 commit 8816aa6

1 file changed

Lines changed: 94 additions & 98 deletions

File tree

Lines changed: 94 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -1,136 +1,133 @@
11

2-
# Fetch: Basics
2+
# Fetch: Основы
33

4-
Method `fetch()` is the modern way of sending requests over HTTP.
4+
Метод `fetch()` — это современный метод отправки HTTP-запросов.
55

6-
It evolved for several years and continues to improve, right now the support is pretty solid among browsers.
6+
На протяжении нескольких лет метод постоянно развивался и до сих пор продолжает улучшаться. В настоящее время его поддерживают все современные браузеры.
77

8-
The basic syntax is:
8+
Базовый синтаксис:
99

1010
```js
1111
let promise = fetch(url, [options])
1212
```
1313

14-
- **`url`** -- the URL to access.
15-
- **`options`** -- optional parameters: method, headers etc.
14+
- **`url`** -- URL для отправки запроса.
15+
- **`options`** -- дополнительные параметры: метод, заголовки и так далее.
1616

17-
The browser starts the request right away and returns a `promise`.
17+
Браузер сразу же начинает запрос и возвращает `promise`.
1818

19-
Getting a response is usually a two-stage process.
19+
Процесс получения ответа обычно происходит в два этапа.
2020

21-
**The `promise` resolves with an object of the built-in [Response](https://fetch.spec.whatwg.org/#response-class) class as soon as the server responds with headers.**
21+
**Результатом `promise` является объект встроенного класса [Response](https://fetch.spec.whatwg.org/#response-class), он появляется, как только сервер пришлет заголовки ответа.**
2222

23+
Таким образом, можно проверить статус HTTP-запроса и определить, выполнился ли он успешно, а также посмотреть заголовки, но пока без тела ответа.
2324

24-
So we can check HTTP status, to see whether it is successful or not, check headers, but don't have the body yet.
25+
Промис завершается с ошибкой, если `fetch` не смог выполнить HTTP-запрос, например при ошибке сети или если нет такого сайта. HTTP-ошибки, такие как 404 или 500, считаются стандартной частью процесса.
2526

26-
The promise rejects if the `fetch` was unable to make HTTP-request, e.g. network problems, or there's no such site. HTTP-errors, even such as 404 or 500, are considered a normal flow.
27+
Мы можем увидеть их в свойствах ответа:
2728

28-
We can see them in response properties:
29+
- **`ok`** -- логическое значение: будет `true`, если код HTTP-статуса в диапазоне 200-299.
30+
- **`status`** -- код статуса HTTP-запроса.
2931

30-
- **`ok`** -- boolean, `true` if the HTTP status code is 200-299.
31-
- **`status`** -- HTTP status code.
32-
33-
For example:
32+
Например:
3433

3534
```js
3635
let response = await fetch(url);
3736

38-
if (response.ok) { // if HTTP-status is 200-299
39-
// get the response body (see below)
37+
if (response.ok) { // если код HTTP-состояния в пределах 200-299
38+
// получаем тело ответа (см. ниже)
4039
let json = await response.json();
4140
} else {
42-
alert("HTTP-Error: " + response.status);
41+
alert("Ошибка HTTP: " + response.status);
4342
}
4443
```
4544

46-
To get the response body, we need to use an additional method call.
45+
Для получения тела ответа нам нужно использовать дополнительный вызов метода.
4746

48-
`Response` provides multiple promise-based methods to access the body in various formats:
47+
`Response` предоставляет несколько методов, основанных на промисах, для доступа к телу ответа в различных форматах:
4948

50-
- **`response.json()`** -- parse the response as JSON object,
51-
- **`response.text()`** -- return the response as text,
52-
- **`response.formData()`** -- return the response as FormData object (form/multipart encoding),
53-
- **`response.blob()`** -- return the response as [Blob](info:blob) (binary data with type),
54-
- **`response.arrayBuffer()`** -- return the response as [ArrayBuffer](info:arraybuffer-binary-arrays) (pure binary data),
55-
- additionally, `response.body` is a [ReadableStream](https://streams.spec.whatwg.org/#rs-class) object, it allows to read the body chunk-by-chunk, we'll see an example later.
49+
- **`response.json()`** -- преобразовывает ответ в JSON-объект,
50+
- **`response.text()`** -- возвращает ответ как обычный текст,
51+
- **`response.formData()`** -- возвращает ответ как объект FormData,
52+
- **`response.blob()`** -- возвращает объект как [Blob](info:blob) (бинарные данные с типом),
53+
- **`response.arrayBuffer()`** -- возвращает ответ как [ArrayBuffer](info:arraybuffer-binary-arrays) (простейшие бинарные данные),
54+
- помимо этого, `response.body` - это объект [ReadableStream](https://streams.spec.whatwg.org/#rs-class), с помощью которого можно считывать тело запроса по частям. Мы рассмотрим пример позже.
5655

57-
For instance, here we get a JSON-object with latest commits from GitHub:
56+
Например, у нас есть JSON-объект с последними коммитами из репозитория на GitHub:
5857

5958
```js run async
6059
let response = await fetch('https://api.github.com/repos/javascript-tutorial/en.javascript.info/commits');
6160

6261
*!*
63-
let commits = await response.json(); // read response body and parse as JSON
62+
let commits = await response.json(); // получаем тело ответа и преобразовываем в JSON
6463
*/!*
6564

6665
alert(commits[0].author.login);
6766
```
6867

69-
Or, the same using pure promises syntax:
68+
Или пример с использованием промисов:
7069

7170
```js run
7271
fetch('https://api.github.com/repos/javascript-tutorial/en.javascript.info/commits')
7372
.then(response => response.json())
7473
.then(commits => alert(commits[0].author.login));
7574
```
7675

77-
To get the text:
76+
Для получения текста:
7877
```js
7978
let text = await response.text();
8079
```
81-
82-
And for the binary example, let's fetch and show an image (see chapter [Blob](info:blob) for details about operations on blobs):
80+
Для примера работы с бинарными данными, давайте запросим и выведем на экран изображение (см. главу [Blob](info:blob), чтобы узнать про операции с Blob):
8381

8482
```js async run
8583
let response = await fetch('/article/fetch/logo-fetch.svg');
8684

8785
*!*
88-
let blob = await response.blob(); // download as Blob object
86+
let blob = await response.blob(); // скачиваем как Blob-объект
8987
*/!*
9088

91-
// create <img> for it
89+
// создаем <img>
9290
let img = document.createElement('img');
9391
img.style = 'position:fixed;top:10px;left:10px;width:100px';
9492
document.body.append(img);
9593

96-
// show it
94+
// выводим на экран
9795
img.src = URL.createObjectURL(blob);
9896

99-
setTimeout(() => { // hide after two seconds
97+
setTimeout(() => { // прячем через две секунды
10098
img.remove();
10199
URL.revokeObjectURL(img.src);
102100
}, 2000);
103101
```
104102

105103
````warn
106-
We can choose only one body-parsing method.
104+
Мы можем выбрать только один метод преобразования.
107105
108-
If we got the response with `response.text()`, then `response.json()` won't work, as the body content has already been processed.
106+
Если мы уже получили ответ с `response.text()`, тогда `response.json()` не сработает, так как данные уже были обработаны.
109107
110108
```js
111-
let text = await response.text(); // response body consumed
112-
let parsed = await response.json(); // fails (already consumed)
109+
let text = await response.text(); // тело ответа обработано
110+
let parsed = await response.json(); // ошибка (данные уже были обработаны)
113111
````
114112

115-
## Headers
113+
## Заголовки
114+
Заголовки хранятся в объекте `response.headers` типа Map.
116115

117-
There's a Map-like headers object in `response.headers`.
118-
119-
We can get individual headers or iterate over them:
116+
Мы можем получить конкретный заголовок или перебрать их в цикле:
120117

121118
```js run async
122119
let response = await fetch('https://api.github.com/repos/javascript-tutorial/en.javascript.info/commits');
123120

124-
// get one header
121+
// получить один заголовок
125122
alert(response.headers.get('Content-Type')); // application/json; charset=utf-8
126123

127-
// iterate over all headers
124+
// перебрать все заголовки
128125
for (let [key, value] of response.headers) {
129126
alert(`${key} = ${value}`);
130127
}
131128
```
132129

133-
To set a header, we can use the `headers` option, like this:
130+
Для установки заголовка, мы можем использовать опцию `headers`, например:
134131

135132
```js
136133
let response = fetch(protectedUrl, {
@@ -140,7 +137,7 @@ let response = fetch(protectedUrl, {
140137
});
141138
```
142139

143-
...But there's a list of [forbidden HTTP headers](https://fetch.spec.whatwg.org/#forbidden-header-name) that we can't set:
140+
...Но существует список [запрещенных HTTP-заголовков](https://fetch.spec.whatwg.org/#forbidden-header-name), которые мы не можем установить:
144141

145142
- `Accept-Charset`, `Accept-Encoding`
146143
- `Access-Control-Request-Headers`
@@ -163,24 +160,24 @@ let response = fetch(protectedUrl, {
163160
- `Proxy-*`
164161
- `Sec-*`
165162

166-
These headers ensure proper and safe HTTP, so they are controlled exclusively by the browser.
163+
Эти заголовки обеспечивают достоверность данных и безопасность протокола HTTP, поэтому они контролируются исключительно браузером.
167164

168-
## POST requests
165+
## POST-запросы
169166

170-
To make a `POST` request, or a request with another method, we need to use `fetch` options:
167+
Для отправки `POST` запроса или запроса с другим методом, нам необходимо использовать `fetch` параметры:
171168

172-
- **`method`** -- HTTP-method, e.g. `POST`,
173-
- **`body`** -- one of:
174-
- a string (e.g. JSON),
175-
- `FormData` object, to submit the data as `form/multipart`,
176-
- `Blob`/`BufferSource` to send binary data,
177-
- [URLSearchParams](info:url), to submit the data as `x-www-form-urlencoded`, rarely used.
169+
- **`method`** -- HTTP метод, например `POST`,
170+
- **`body`** -- один из:
171+
- строка (например JSON),
172+
- объект `FormData` для отправки данных как `form/multipart`,
173+
- `Blob`/`BufferSource` для отправки бинарных данных,
174+
- [URLSearchParams](info:url) для отправки таких данных как `x-www-form-urlencoded`, используется очень редко.
178175

179-
Let's see examples.
176+
Рассмотрим примеры:
180177

181-
## Submit JSON
178+
## Отправка JSON
182179

183-
This code submits a `user` object as JSON:
180+
Этот код отправляет объект `user` как JSON:
184181

185182
```js run async
186183
let user = {
@@ -201,12 +198,11 @@ let response = await fetch('/article/fetch-basics/post/user', {
201198
let result = await response.json();
202199
alert(result.message);
203200
```
201+
Обратите внимание, если тело ответа - строка, то `Content-Type` установлен как `text/plain;charset=UTF-8` по умолчанию. Поэтому мы используем параметр `headers` для отправки `application/json`.
204202

205-
Please note, if the body is a string, then `Content-Type` is set to `text/plain;charset=UTF-8` by default. So we use `headers` option to send `application/json` instead.
206-
207-
## Submit a form
203+
## Отправка формы
208204

209-
Let's do the same with an HTML `<form>`.
205+
Давайте сделаем то же самое с HTML `<form>`.
210206

211207

212208
```html run
@@ -231,19 +227,19 @@ Let's do the same with an HTML `<form>`.
231227
</script>
232228
```
233229

234-
Here [FormData](https://xhr.spec.whatwg.org/#formdata) automatically encodes the form, `<input type="file">` fields are handled also, and sends it using `Content-Type: form/multipart`.
230+
Объект [FormData](https://xhr.spec.whatwg.org/#formdata) автоматически кодирует данные формы, поля `<input type="file">` также обрабатываются, а затем отправляет их с использованием заголовка `Content-Type: form/multipart`.
235231

236-
## Submit an image
232+
## Отправка изображения
237233

238-
We can also submit binary data directly using `Blob` or `BufferSource`.
234+
Мы можем отправить бинарные данные напрямую, используя `Blob` или `BufferSource`.
239235

240-
For example, here's a `<canvas>` where we can draw by moving a mouse. A click on the "submit" button sends the image to server:
236+
Например, у нас есть элемент `<canvas>`, на котором мы можем рисовать движением мыши. При нажатии на кнопку "Отправить", изображение отправляется на сервер:
241237

242238
```html run autorun height="90"
243239
<body style="margin:0">
244240
<canvas id="canvasElem" width="100" height="80" style="border:1px solid"></canvas>
245241

246-
<input type="button" value="Submit" onclick="submit()">
242+
<input type="button" value="Отправить" onclick="submit()">
247243

248244
<script>
249245
canvasElem.onmousemove = function(e) {
@@ -266,9 +262,9 @@ For example, here's a `<canvas>` where we can draw by moving a mouse. A click on
266262
</body>
267263
```
268264

269-
Here we also didn't need to set `Content-Type` manually, because a `Blob` object has a built-in type (here `image/png`, as generated by `toBlob`).
265+
В этом случае нам не нужно вручную устанавливать заголовок `Content-Type`, потому что объект `Blob` имеет встроенный тип (в показанном примере это `image/png`, созданный методом `toBlob`).
270266

271-
The `submit()` function can be rewritten without `async/await` like this:
267+
Функция `submit()` может быть переписана без `async/await` например так:
272268

273269
```js
274270
function submit() {
@@ -283,17 +279,17 @@ function submit() {
283279
}
284280
```
285281

286-
## Custom FormData with image
282+
## Создание FormData с изображением
287283

288-
In practice though, it's often more convenient to send an image as a part of the form, with additional fields, such as "name" and other metadata.
284+
Всё-таки на практике удобнее отправлять изображения в качестве части данных формы с дополнительными полями, такими как "name" или другими метаданными.
289285

290-
Also, servers are usually more suited to accept multipart-encoded forms, rather than raw binary data.
286+
Помимо этого, серверы обычно предназначены для получения данных, закодированных методом multipart/form-data, нежели чем простых бинарных данных.
291287

292288
```html run autorun height="90"
293289
<body style="margin:0">
294290
<canvas id="canvasElem" width="100" height="80" style="border:1px solid"></canvas>
295291

296-
<input type="button" value="Submit" onclick="submit()">
292+
<input type="button" value="Отправить" onclick="submit()">
297293

298294
<script>
299295
canvasElem.onmousemove = function(e) {
@@ -323,39 +319,39 @@ Also, servers are usually more suited to accept multipart-encoded forms, rather
323319
</body>
324320
```
325321

326-
Now, from the server standpoint, the image is a "file" in the form.
322+
Теперь с точки зрения сервера, изображение это файл в форме.
327323

328-
## Summary
324+
## Итого
329325

330-
A typical fetch request consists of two `awaits`:
326+
Типичный запрос с помощью `fetch` состоит из двух операторов `await`:
331327

332328
```js
333-
let response = await fetch(url, options); // resolves with response headers
334-
let result = await response.json(); // read body as json
329+
let response = await fetch(url, options); // завершается с заголовками ответа
330+
let result = await response.json(); // преобразует тело ответа в JSON
335331
```
336332

337-
Or, promise-style:
333+
Или с помощью промисов:
338334
```js
339335
fetch(url, options)
340336
.then(response => response.json())
341-
.then(result => /* process result */)
337+
.then(result => /* обрабатываем результат */)
342338
```
343339

344-
Response properties:
345-
- `response.status` -- HTTP code of the response,
346-
- `response.ok` -- `true` is the status is 200-299.
347-
- `response.headers` -- Map-like object with HTTP headers.
340+
Параметры ответа:
341+
- `response.status` -- HTTP-код ответа,
342+
- `response.ok` -- `true`, если статус ответа в диапазоне 200-299.
343+
- `response.headers` -- похожий на объект типа Map с HTTP-заголовками.
348344

349-
Methods to get response body:
350-
- **`response.json()`** -- parse the response as JSON object,
351-
- **`response.text()`** -- return the response as text,
352-
- **`response.formData()`** -- return the response as FormData object (form/multipart encoding),
353-
- **`response.blob()`** -- return the response as [Blob](info:blob) (binary data with type),
354-
- **`response.arrayBuffer()`** -- return the response as [ArrayBuffer](info:arraybuffer-binary-arrays) (pure binary data),
345+
Методы для получения тела ответа:
346+
- **`response.json()`** -- преобразовывает ответ в JSON-объект,
347+
- **`response.text()`** -- возвращает ответ как обычный текст,
348+
- **`response.formData()`** -- возвращает ответ как объект FormData (кодировка form/multipart),
349+
- **`response.blob()`** -- возвращает объект как [Blob](info:blob) (бинарные данные с типом),
350+
- **`response.arrayBuffer()`** -- возвращает ответ как [ArrayBuffer](info:arraybuffer-binary-arrays) (простейшие бинарные данные),
355351

356-
Fetch options so far:
357-
- `method` -- HTTP-method,
358-
- `headers` -- an object with request headers (not any header is allowed),
359-
- `body` -- string/FormData/BufferSource/Blob/UrlSearchParams data to submit.
352+
Параметры:
353+
- `method` -- HTTP-метод,
354+
- `headers` -- объект с запрашиваемыми заголовками (не все заголовка разрешены),
355+
- `body` -- данные для отправки в виде текста/FormData/BufferSource/Blob/UrlSearchParams.
360356

361-
In the next chapters we'll see more options and use cases.
357+
В следующих главах мы рассмотрим больше параметров и вариантов использования.

0 commit comments

Comments
 (0)