This commit is contained in:
Ilya Kantor 2019-07-04 18:13:00 +03:00
parent b300836f00
commit b1b66a3065
9 changed files with 61 additions and 85 deletions

View file

@ -12,7 +12,7 @@ For example, we can:
...And all of that without reloading the page!
There's an umbrella term "AJAX" (abbreviated <b>A</b>synchronous <b>J</b>avascript <b>A</b>nd <b>X</b>ml) for that. We don't have to use XML though: the term comes from old times, that's why it's here.
There's an umbrella term "AJAX" (abbreviated <b>A</b>synchronous <b>J</b>avascript <b>A</b>nd <b>X</b>ml) for that. We don't have to use XML though: the term comes from old times, that's that word is there.
There are multiple ways to send a network request and get information from the server.
@ -33,7 +33,6 @@ Getting a response is usually a two-stage process.
**First, 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.**
So we can check HTTP status, to see whether it is successful or not, check headers, but don't have the body yet.
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.
@ -67,7 +66,7 @@ if (response.ok) { // if HTTP-status is 200-299
- **`response.arrayBuffer()`** -- return the response as [ArrayBuffer](info:arraybuffer-binary-arrays) (pure binary data),
- 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.
For instance, here we get a JSON-object with latest commits from GitHub:
For instance, let's get a JSON-object with latest commits from GitHub:
```js run async
let response = await fetch('https://api.github.com/repos/javascript-tutorial/en.javascript.info/commits');
@ -79,7 +78,7 @@ let commits = await response.json(); // read response body and parse as JSON
alert(commits[0].author.login);
```
Or, the same using pure promises syntax:
Or, the same without `await`, using pure promises syntax:
```js run
fetch('https://api.github.com/repos/javascript-tutorial/en.javascript.info/commits')
@ -191,9 +190,7 @@ To make a `POST` request, or a request with another method, we need to use `fetc
- a string (e.g. JSON),
- `FormData` object, to submit the data as `form/multipart`,
- `Blob`/`BufferSource` to send binary data,
- [URLSearchParams](info:url), to submit the data as `x-www-form-urlencoded`, rarely used.
Let's see examples.
- [URLSearchParams](info:url), to submit the data in `x-www-form-urlencoded` encoding, rarely used.
For example, this code submits `user` object as JSON:
@ -271,7 +268,7 @@ function submit() {
## Summary
A typical fetch request consists of two `awaits`:
A typical fetch request consists of two `await` calls:
```js
let response = await fetch(url, options); // resolves with response headers
@ -302,4 +299,4 @@ Fetch options so far:
- `headers` -- an object with request headers (not any header is allowed),
- `body` -- `string`, `FormData`, `BufferSource`, `Blob` or `UrlSearchParams` object to send.
In the next chapters we'll see more options and use cases.
In the next chapters we'll see more options and use cases of `fetch`.

View file

@ -7,7 +7,7 @@ Please note: there's currently no way for `fetch` to track *upload* progress. Fo
To track download progress, we can use `response.body` property. It's a "readable stream" -- a special object that provides body chunk-by-chunk, as it comes.
Unlike `response.text()`, `response.json()` and other methods, `response.body` gives full control over the reading process, and we can see how much is consumed at the moment.
Unlike `response.text()`, `response.json()` and other methods, `response.body` gives full control over the reading process, and we can count how much is consumed at any moment.
Here's the sketch of code that reads the reponse from `response.body`:
@ -29,13 +29,13 @@ while(true) {
}
```
So, we read response chunks in the loop, while `await reader.read()` returns them. When it's done, no more data, so we're done.
The result of `await reader.read()` call is an object with two properties:
- **`done`** -- true when the reading is complete.
- **`value`** -- a typed array of bytes: `Uint8Array`.
To log progress, we just need for every `value` add its length to the counter.
We wait for more chunks in the loop, until `done` is `true`.
To log the progress, we just need for every `value` add its length to the counter.
Here's the full code to get response and log the progress, more explanations follow:

View file

@ -48,12 +48,11 @@ One way to communicate with another server was to submit a `<form>` there. Peopl
*/!*
...
</form>
```
So, it was possible to make a GET/POST request to another site, even without networking methods. But as it's forbidden to access the content of an `<iframe>` from another site, it wasn't possible to read the response.
...Okay, in fact there actually were tricks for that (required special scripts at both remote and our page), but let's not delve deeper. Nothing good in those for us now.
As we can see, forms allowed to send data anywhere, but not receive the response. To be precise, there wre actually tricks for that (required special scripts at both the iframe and the page), but let these dinosaurs rest in peace.
### Using scripts

View file

@ -73,7 +73,7 @@ We can provide them in the URL string:
new URL('https://google.com/search?query=JavaScript')
```
...But that's not good due to encoding issues. Parameters need to be encoded if they contain spaces, non-latin letterrs, etc (more about that below).
...But parameters need to be encoded if they contain spaces, non-latin letters, etc (more about that below).
So there's URL property for that: `url.searchParams`, an object of type [URLSearchParams](https://url.spec.whatwg.org/#urlsearchparams).
@ -96,7 +96,7 @@ url.searchParams.set('q', 'test me!'); // added parameter with a space and !
alert(url); // https://google.com/search?query=test+me%21
url.searchParams.set('tbs', 'qdr:y'); // add param for date range: past year
url.searchParams.set('tbs', 'qdr:y'); // this parameter specifies for date range for Google Search
alert(url); // https://google.com/search?q=test+me%21&tbs=qdr%3Ay

View file

@ -220,11 +220,7 @@ We can terminate the request at any time. The call to `xhr.abort()` does that:
xhr.abort(); // terminate the request
```
That triggers `abort` event.
That
Also, `x and `xhr.status` become `0` in that case.
That triggers `abort` event, and `xhr.status` becomes `0`.
## Synchronous requests
@ -248,7 +244,7 @@ try {
}
} catch(err) { // instead of onerror
alert("Request failed");
};
}
```
It might look good, but synchronous calls are used rarely, because they block in-page JavaScript till the loading is complete. In some browsers it becomes impossible to scroll. If a synchronous call takes too much time, the browser may suggest to close the "hanging" webpage.
@ -489,7 +485,7 @@ let xhr = new XMLHttpRequest();
xhr.open('GET', '/my/url');
xhr.send(); s
xhr.send();
xhr.onload = function() {
if (xhr.status != 200) { // HTTP error?
@ -521,9 +517,9 @@ There are actually more events, the [modern specification](http://www.w3.org/TR/
- `timeout` -- the request was canceled due to timeout (only happens if it was set).
- `loadend` -- triggers after `load`, `error`, `timeout` or `abort`.
The `error`, `abort`, `timeout`, and `load` events are mutually exclusive.
The `error`, `abort`, `timeout`, and `load` events are mutually exclusive. Only one of them may happen.
The most used events are load completion (`load`), load failure (`error`), or we can use a single `loadend` handler and check event and response to see what happened.
The most used events are load completion (`load`), load failure (`error`), or we can use a single `loadend` handler and check the response to see what happened.
We've already seen another event: `readystatechange`. Historically, it appeared long ago, before the specification settled. Nowadays, there's no need to use it, we can replace it with newer events, but it can often be found in older scripts.