From e8b6c592382a9db9c444976a72f605ecd31bfd52 Mon Sep 17 00:00:00 2001 From: mitroc Date: Sat, 5 Oct 2019 20:29:53 +0200 Subject: [PATCH 01/12] Translated 'sever.js' --- 5-network/01-fetch/post.view/server.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/5-network/01-fetch/post.view/server.js b/5-network/01-fetch/post.view/server.js index b55870b2a..b9a2a9bed 100644 --- a/5-network/01-fetch/post.view/server.js +++ b/5-network/01-fetch/post.view/server.js @@ -8,7 +8,7 @@ let router = new Router(); router.post('/user', async (ctx) => { ctx.body = { - message: "User saved." + message: "Zapisano użytkownika." }; }); @@ -17,7 +17,7 @@ router.post('/image', async (ctx) => { limit: '1mb' }); ctx.body = { - message: `Image saved, size:${body.length}.` + message: `Zapisano obraz, rozmiar:${body.length}.` }; }); From 9470b2a3fc5665103a239cce3efefc0a00479fea Mon Sep 17 00:00:00 2001 From: mitroc Date: Sat, 5 Oct 2019 20:32:07 +0200 Subject: [PATCH 02/12] Translate 'task.md' --- 5-network/01-fetch/01-fetch-users/task.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/5-network/01-fetch/01-fetch-users/task.md b/5-network/01-fetch/01-fetch-users/task.md index 4605b4955..b4ea5f2d4 100644 --- a/5-network/01-fetch/01-fetch-users/task.md +++ b/5-network/01-fetch/01-fetch-users/task.md @@ -1,13 +1,13 @@ -# Fetch users from GitHub +# Pobierz użytkowników z GitHuba -Create an async function `getUsers(names)`, that gets an array of GitHub logins, fetches the users from GitHub and returns an array of GitHub users. +Stwórz asynchroniczną funkcję `getUsers(names)`, która pobiera z GitHuba tablicę z nazwami użytkowników, a następnie zwraca tablicę z odpowiadającymi im użytkownikami. -The GitHub url with user information for the given `USERNAME` is: `https://api.github.com/users/USERNAME`. +Informacje o użytkowniku przypisanym do `USERNAME`, znajdują się pod adresem url: `https://api.github.com/users/USERNAME`. -There's a test example in the sandbox. +W środowisku izolowanym znajduje się przykład testowy. -Important details: +Ważne informacje: -1. There should be one `fetch` request per user. -2. Requests shouldn't wait for each other. So that the data arrives as soon as possible. -3. If any request fails, or if there's no such user, the function should return `null` in the resulting array. +1. Można wykonać tylko jedno żądanie `fetch` o dane użytkownika. +2. Żądania nie powinny na siebie oczekiwać. Chodzi o to, aby dane dotarły jak najszybciej. +3. Jeżeli żądanie się nie powiedzie lub nie będzie użytkownika o podanej nazwie, funkcja powinna zwrócić `null` w tablicy wynikowej. \ No newline at end of file From 27af43f1b8ed8273f4942ccafaec50740a5d779d Mon Sep 17 00:00:00 2001 From: mitroc Date: Sat, 5 Oct 2019 20:33:47 +0200 Subject: [PATCH 03/12] Translate 'solution' --- 5-network/01-fetch/01-fetch-users/solution.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/5-network/01-fetch/01-fetch-users/solution.md b/5-network/01-fetch/01-fetch-users/solution.md index b8dfb62a2..8afaa86cd 100644 --- a/5-network/01-fetch/01-fetch-users/solution.md +++ b/5-network/01-fetch/01-fetch-users/solution.md @@ -1,11 +1,11 @@ -To fetch a user we need: `fetch('https://api.github.com/users/USERNAME')`. +Aby pobrać użytkownika wykorzystamy: `fetch('https://api.github.com/users/USERNAME')`. -If the response has status `200`, call `.json()` to read the JS object. +Jeżeli odpowiedź zostanie zwrócona ze statusem `200`, wywołamy metodę `.json()`, aby móc odczytać javascriptowy obiekt. -Otherwise, if a `fetch` fails, or the response has non-200 status, we just return `null` in the resulting arrray. +Jeżeli natomiast `fetch` się nie powiedzie lub status odpowiedzi będzie inny niz 200, wówczas w tablicy wynikowej zwracamy po prostu `null`. -So here's the code: +Kod wygląda następująco: ```js demo async function getUsers(names) { @@ -33,8 +33,8 @@ async function getUsers(names) { } ``` -Please note: `.then` call is attached directly to `fetch`, so that when we have the response, it doesn't wait for other fetches, but starts to read `.json()` immediately. +Zauważ, że metoda `.then` jest dołączona bezpośrednio do `fetch`, więc nie czeka ona na kolejne żądania, lecz jak tylko otrzyma odpowiedź, natychmiast odczytuje ją przy użyciu metody `.json()`. -If we used `await Promise.all(names.map(name => fetch(...)))`, and call `.json()` on the results, then it would wait for all fetches to respond. By adding `.json()` directly to each `fetch`, we ensure that individual fetches start reading data as JSON without waiting for each other. +Gdybyśmy jednak użyli `await Promise.all(names.map(name => fetch(...)))` i wywołali metodę `.json()` dopiero na rezultacie, wówczas musiałaby ona czekać, aż wszystkie żądania zwrócą swoje odpowiedzi. Dołączając `.json()` bezpośrednio do każdego zapytania `fetch` możemy być pewni, że pojedyncze zapytania zaczną odczytywać dane jako JSON, bez czekania nawzajem na siebie. -That's an example of how low-level Promise API can still be useful even if we mainly use `async/await`. +Jest to przykład tego, jak przydatne może być niskopoziomowe Promise API, nawet jeżeli głównie korzystamy z `async/await`. \ No newline at end of file From d9a9d017bdda357d66c50c25eb7deb52ccb15eb2 Mon Sep 17 00:00:00 2001 From: mitroc Date: Sat, 5 Oct 2019 20:35:22 +0200 Subject: [PATCH 04/12] Translate 'test.js' --- 5-network/01-fetch/01-fetch-users/_js.view/test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/5-network/01-fetch/01-fetch-users/_js.view/test.js b/5-network/01-fetch/01-fetch-users/_js.view/test.js index 95eaf876e..ed8d03137 100644 --- a/5-network/01-fetch/01-fetch-users/_js.view/test.js +++ b/5-network/01-fetch/01-fetch-users/_js.view/test.js @@ -1,7 +1,7 @@ describe("getUsers", function() { - it("gets users from GitHub", async function() { - let users = await getUsers(['iliakan', 'remy', 'no.such.users']); + it("pobiera użytkowników GitHuba", async function() { + let users = await getUsers(['iliakan', 'remy', 'brak.użytkowników']); assert.equal(users[0].login, 'iliakan'); assert.equal(users[1].login, 'remy'); assert.equal(users[2], null); From 835aaba9d7c31d00e924a777cfc3c3523aa736bd Mon Sep 17 00:00:00 2001 From: mitroc Date: Sat, 5 Oct 2019 20:36:15 +0200 Subject: [PATCH 05/12] Translated 'source.js' --- 5-network/01-fetch/01-fetch-users/_js.view/source.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/5-network/01-fetch/01-fetch-users/_js.view/source.js b/5-network/01-fetch/01-fetch-users/_js.view/source.js index 0c62e7bb5..4a5d2bbe1 100644 --- a/5-network/01-fetch/01-fetch-users/_js.view/source.js +++ b/5-network/01-fetch/01-fetch-users/_js.view/source.js @@ -1,4 +1,4 @@ async function getUsers(names) { - /* your code */ + /* twój kod */ } From 363bc8e29a28b90d9af9db79d71bd8327d9e51e1 Mon Sep 17 00:00:00 2001 From: mitroc Date: Sat, 5 Oct 2019 22:23:01 +0200 Subject: [PATCH 06/12] Translated 'article.md' --- 5-network/01-fetch/article.md | 192 +++++++++++++++++----------------- 1 file changed, 96 insertions(+), 96 deletions(-) diff --git a/5-network/01-fetch/article.md b/5-network/01-fetch/article.md index 1170042e0..6983abfb5 100644 --- a/5-network/01-fetch/article.md +++ b/5-network/01-fetch/article.md @@ -1,74 +1,74 @@ # Fetch -JavaScript can send network requests to the server and load new information whenever is needed. +Ilekroć jest to potrzebne, JavaScript potrafi wykonywać żądania sieciowe do serwera i pobierać nowe informacje. -For example, we can use a network request to: +Można na przykład użyć zapytania sieciowego do: -- Submit an order, -- Load user information, -- Receive latest updates from the server, -- ...etc. +- złożenia zamówienia, +- wyświetlenia informacji o użytkowniku, +- otrzymania najnowszych aktualizacji z serwera, +- ...itp. -...And all of that without reloading the page! +...I to wszystko bez przeładowania strony! -There's an umbrella term "AJAX" (abbreviated Asynchronous JavaScript And XML) for network requests from JavaScript. We don't have to use XML though: the term comes from old times, that's why that word is there. You may have heard that term already. +Istnieje nadrzędny termin "AJAX" (skrót od Asynchronous JavaScript And XML) dotyczący żądań sieciowych w JavaScript. Nie musimy jednak używać XML-a: skrót ten pochodzi z dawnych czasów, stąd też zawiera takie właśnie słowo. Być może znasz już ten termin. -There are multiple ways to send a network request and get information from the server. +Istnieje wiele sposobów wysłania żądania sieciowego i pobrania informacji z serwera. -The `fetch()` method is modern and versatile, so we'll start with it. It's not supported by old browsers (can be polyfilled), but very well supported among the modern ones. +Metoda `fetch()` jest nowoczesna i wszechstronna, zaczniemy więc od niej. Nie jest ona wspierana przez stare przeglądarki (można ją zaimplementować skryptem typu polyfill), jest natomiast bardzo dobrze obsługiwana przez współczesne przeglądarki. -The basic syntax is: +Podstawowa składnia jest następująca: ```js let promise = fetch(url, [options]) ``` -- **`url`** -- the URL to access. -- **`options`** -- optional parameters: method, headers etc. +- **`url`** -- adres URL zapytania. +- **`options`** -- parametry opcjonalne: metoda, nagłówki, itp. -Without `options`, that is a simple GET request, downloading the contents of the `url`. +Bez `options` mamy do czynienia ze zwykłym zapytaniem GET, pobierającym zawartość adresu `url`. -The browser starts the request right away and returns a promise that the calling code should use to get the result. +Przeglądarka natychmiast uruchamia zapytanie i zwraca obietnicę (ang. *promise*), której kod (wywołujący owo zapytanie) powinien użyć do uzyskania wyniku. -Getting a response is usually a two-stage process. +Uzyskanie odpowiedzi jest zwykle procesem dwuetapowym. -**First, the `promise`, returned by `fetch`, 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.** +**Po pierwsze `obietnica`, zwrócona przez `fetch`, rozwiązuje się za pomocą obiektu wbudowanej klasy [Response](https://fetch.spec.whatwg.org/#response-class) , gdy tylko serwer odpowie nagłówkami.** -At this stage we can check HTTP status, to see whether it is successful or not, check headers, but don't have the body yet. +Na tym etapie możemy sprawdzić status HTTP, aby zobaczyć czy zapytanie się powiodło czy nie, możemy również sprawdzić nagłówki, ale jeszcze nie mamy dostępu do ciała odpowiedzi. -The promise rejects if the `fetch` was unable to make HTTP-request, e.g. network problems, or there's no such site. Abnormal HTTP-statuses, such as 404 or 500 do not cause an error. +Obietnica zostaje odrzucona jeżeli `fetch` nie był w stanie wykonać zapytania HTTP, np. ze względu problemy sieciowe lub brak strony, do której skierowano zapytanie. Nieprawidłowe statusy HTTP takie jak 404 lub 500 nie powodują błędu. -We can see HTTP-status in response properties: +Informację o statusie HTTP znajdziemy wśród właściwości odpowiedzi: -- **`status`** -- HTTP status code, e.g. 200. -- **`ok`** -- boolean, `true` if the HTTP status code is 200-299. +- **`status`** -- kod odpowiedzi HTTP, np. 200. +- **`ok`** -- typ logiczny, `true` jeżeli kod odpowiedzi HTTP jest z zakresu 200-299. -For example: +Przykładowo: ```js let response = await fetch(url); -if (response.ok) { // if HTTP-status is 200-299 - // get the response body (the method explained below) +if (response.ok) { // jeżeli kod odpowiedzi HTTP jest z zakresu 200-299 + // pobierz ciało odpowiedzi (wyjaśnienie metody poniżej) let json = await response.json(); } else { - alert("HTTP-Error: " + response.status); + alert("Błąd HTTP: " + response.status); } ``` -**Second, to get the response body, we need to use an additional method call.** +**Po drugie, aby pobrać ciało odpowiedzi należy wywołać kolejną metodę.** -`Response` provides multiple promise-based methods to access the body in various formats: +`Response` (pol. *odpowiedź*) zapewnia wiele metod, bazujących na obietnicach, które pozwalają na dostęp do ciała odpowiedzi i zwrócenie go w różnych formach: -- **`response.text()`** -- read the response and return as text, -- **`response.json()`** -- parse the response as JSON, -- **`response.formData()`** -- return the response as `FormData` object (explained in the [next chapter](info:formdata)), -- **`response.blob()`** -- return the response as [Blob](info:blob) (binary data with type), -- **`response.arrayBuffer()`** -- return the response as [ArrayBuffer](info:arraybuffer-binary-arrays) (low-level representaion of 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. +- **`response.text()`** -- odczytaj odpowiedź i zwróć jako tekst, +- **`response.json()`** -- odczytaj odpowiedź i zwróć jako JSON, +- **`response.formData()`** -- zwróć odpowiedź jako obiekt typu `FormData` (wyjaśnienie w [następnym rozdziale](info:formdata)), +- **`response.blob()`** -- zwróć odpowiedź jako [Blob](info:blob) (dane binarne z typem), +- **`response.arrayBuffer()`** -- zwróć odpowiedź jako [ArrayBuffer](info:arraybuffer-binary-arrays) (niskopoziomowa reprezentacja danych binarnych), +- ponadto `response.body` jest sam w sobie obiektem typu [ReadableStream](https://streams.spec.whatwg.org/#rs-class), co pozwala na odczytywanie go kawałek po kawałku, co zostanie pokazane w kolejnym przykładzie. -For instance, let's get a JSON-object with latest commits from GitHub: +Pobierzmy dla przykładu obiekt JSON z ostatnimi commitami z GitHuba. ```js run async let url = 'https://api.github.com/repos/javascript-tutorial/en.javascript.info/commits'; @@ -81,7 +81,7 @@ let commits = await response.json(); // read response body and parse as JSON alert(commits[0].author.login); ``` -Or, the same without `await`, using pure promises syntax: +Bądź to samo, ale bez `await`, a jedynie za pomocą czystej składni obietnic: ```js run fetch('https://api.github.com/repos/javascript-tutorial/en.javascript.info/commits') @@ -89,70 +89,70 @@ fetch('https://api.github.com/repos/javascript-tutorial/en.javascript.info/commi .then(commits => alert(commits[0].author.login)); ``` -To get the reponse text, `await response.text()` instead of `.json()`: +Aby pobrać odpowiedź jako tekst, użyj `await response.text()` zamiast `.json()`: ```js run async let response = await fetch('https://api.github.com/repos/javascript-tutorial/en.javascript.info/commits'); -let text = await response.text(); // read response body as text +let text = await response.text(); // odczytaj ciało odpowiedzi jako tekst alert(text.slice(0, 80) + '...'); ``` -As a show-case for reading in binary format, let's fetch and show a logo image of ["fetch" specification](https://fetch.spec.whatwg.org) (see chapter [Blob](info:blob) for details about operations on `Blob`): +Aby zaprezentować odczyt danych w formacie binarnym, pobierzmy obraz logo [specyfikacji "fetch"](https://fetch.spec.whatwg.org) (patrz rozdział [Blob](info:blob) odnośnie operacji na obiekcie typu `Blob`): ```js async run let response = await fetch('/article/fetch/logo-fetch.svg'); *!* -let blob = await response.blob(); // download as Blob object +let blob = await response.blob(); // pobierz logo jako obiekt typu Blob */!* -// create for it +// stwórz dla niego znacznik let img = document.createElement('img'); img.style = 'position:fixed;top:10px;left:10px;width:100px'; document.body.append(img); -// show it +// wyświetl je img.src = URL.createObjectURL(blob); -setTimeout(() => { // hide after three seconds +setTimeout(() => { // ukryj po upływie trzech sekund img.remove(); URL.revokeObjectURL(img.src); }, 3000); ``` ````warn -We can choose only one body-reading method. +Można wybrać tyko jedną z metod odczytywania ciała odpowiedzi. -If we've already got the response with `response.text()`, then `response.json()` won't work, as the body content has already been processed. +Jeśli już zdecydowaliśmy się na `response.text()`, wówczas `response.json()` nie zadziała, ponieważ zawartość ciała odpowiedzi została już wcześniej przetworzona. ```js -let text = await response.text(); // response body consumed -let parsed = await response.json(); // fails (already consumed) +let text = await response.text(); // ciało odpowiedzi zostaje przetworzone +let parsed = await response.json(); // nie powiedzie się (przetworzone wcześniej) ```` -## Response headers +## Nagłówki odpowiedzi -The response headers are available in a Map-like headers object in `response.headers`. +Nagłówki odpowiedzi są dostępne w obiekcie nagłówków podobnym do obiektu Map, a konkretnie w `response.headers`. -It's not exactly a Map, but it has similar methods to get individual headers by name or iterate over them: +Nie jest do dokładnie Map, aczkolwiek posiada podobne metody, służące do pobrania poszczególnych nagłówków za pomocą nazwy lub poprzez iterowanie po nich: ```js run async let response = await fetch('https://api.github.com/repos/javascript-tutorial/en.javascript.info/commits'); -// get one header +// pobieramy jeden nagłówek alert(response.headers.get('Content-Type')); // application/json; charset=utf-8 -// iterate over all headers +// iterujemy po wszystkich nagłówkach for (let [key, value] of response.headers) { alert(`${key} = ${value}`); } ``` -## Request headers +## Nagłówki żądania -To set a request header in `fetch`, we can use the `headers` option. It has an object with outgoing headers, like this: +Aby zdefiniować nagłówek w żądaniu `fetch`, użyjemy właściwości `headers`, która zawiera obiekt z wychodzącymi nagłówkami: ```js let response = fetch(protectedUrl, { @@ -162,7 +162,7 @@ let response = fetch(protectedUrl, { }); ``` -...But there's a list of [forbidden HTTP headers](https://fetch.spec.whatwg.org/#forbidden-header-name) that we can't set: +... Istnieją również [zabronione nagłówki HTTP](https://fetch.spec.whatwg.org/#forbidden-header-name), których nie możemy zdefiniować: - `Accept-Charset`, `Accept-Encoding` - `Access-Control-Request-Headers` @@ -185,27 +185,27 @@ let response = fetch(protectedUrl, { - `Proxy-*` - `Sec-*` -These headers ensure proper and safe HTTP, so they are controlled exclusively by the browser. +Dzięki nim protokół HTTP działa prawidłowo i jest bezpieczny, dlatego też są pod pełną kontrolą przeglądarki. -## POST requests +## Żądania POST -To make a `POST` request, or a request with another method, we need to use `fetch` options: +Ażeby wykonać żądanie typu `POST` lub jakiekolwiek inne żądanie sieciowe musimy użyć opcji dostępnych w metodzie `fetch`: -- **`method`** -- HTTP-method, e.g. `POST`, -- **`body`** -- the request body, one of: - - a string (e.g. JSON-encoded), - - `FormData` object, to submit the data as `form/multipart`, - - `Blob`/`BufferSource` to send binary data, - - [URLSearchParams](info:url), to submit the data in `x-www-form-urlencoded` encoding, rarely used. +- **`method`** -- metoda HTTP, np. `POST`, +- **`body`** -- ciało żądania, może przyjąć formę: + - łańcucha znaków (np. w formacie JSON), + - obiektu `FormData`, aby móc przesłać dane jako `form/multipart`, + - `Blob`/`BufferSource`, aby przesłać dane w formie binarnej, + - [URLSearchParams](info:url), aby przesłać dane jako `x-www-form-urlencoded`, rzadko używane. -The JSON format is used most of the time. +Najczęściej używanym formatem jest JSON. -For example, this code submits `user` object as JSON: +Przykładowo, ten kod przesyła obiekt `user` jako JSON: ```js run async let user = { - name: 'John', - surname: 'Smith' + name: 'Jan', + surname: 'Kowalski' }; *!* @@ -222,15 +222,15 @@ let result = await response.json(); alert(result.message); ``` -Please note, if the request `body` is a string, then `Content-Type` header is set to `text/plain;charset=UTF-8` by default. +Należy pamiętać, że jeżeli ciało żądania (`body`) jest łańcuchem znaków, wówczas nagłówek `Content-Type` domyślnie ustawiony jest jako `text/plain;charset=UTF-8`. -But, as we're going to send JSON, we use `headers` option to send `application/json` instead, the correct `Content-Type` for JSON-encoded data. +Ponieważ jednak zamierzamy wysłać obiekt JSON, użyjemy obiektu `headers` do ustawienia nagłówka `Content-Type` jako `application/json`, czyli właściwego dla danych zakodowanych w formacie JSON. -## Sending an image +## Wysyłanie obrazu -We can also submit binary data with `fetch` using `Blob` or `BufferSource` objects. +Możemy także za pomocą `fetch`przesłać dane binarne, używając obiektów `Blob` albo `BufferSource`. -In this example, there's a `` where we can draw by moving a mouse over it. A click on the "submit" button sends the image to server: +W poniższym przykładzie mamy znacznik ``, który pozwala na rysowanie poprzez poruszanie nad nim myszką. Kliknięcie na przycisk "Prześlij" wysyła obraz do serwera: ```html run autorun height="90" @@ -252,7 +252,7 @@ In this example, there's a `` where we can draw by moving a mouse over i body: blob }); - // the server responds with confirmation and the image size + // serwer potwierdza zapisanie obrazu oraz podaje jego rozmiar let result = await response.json(); alert(result.message); } @@ -261,9 +261,9 @@ In this example, there's a `` where we can draw by moving a mouse over i ``` -Please note, here we don't set `Content-Type` header manually, because a `Blob` object has a built-in type (here `image/png`, as generated by `toBlob`). For `Blob` objects that type becomes the value of `Content-Type`. +Zauważ, że nie ustawiamy ręcznie nagłówka `Content-Type`, ponieważ obiekt `Blob` posiada wbudowany typ (tutaj `image/png`, wymuszony przez metodę `toBlob`). Dla obiektów `Blob` ten typ zostaje ustawiony dla nagłówka `Content-Type`. -The `submit()` function can be rewritten without `async/await` like this: +Funkcję `submit()` można również przepisać nie używając składni `async/await` w taki sposób: ```js function submit() { @@ -278,13 +278,13 @@ function submit() { } ``` -## Summary +## Podsumowanie -A typical fetch request consists of two `await` calls: +Typowe żądanie `fetch` składa się z dwóch wywołań metody `await`: ```js -let response = await fetch(url, options); // resolves with response headers -let result = await response.json(); // read body as json +let response = await fetch(url, options); // rozwiązuje się z nagłówkami odpowiedzi +let result = await response.json(); // odczytuje ciało jako JSON ``` Or, without `await`: @@ -292,24 +292,24 @@ Or, without `await`: ```js fetch(url, options) .then(response => response.json()) - .then(result => /* process result */) + .then(result => /* zrób coś z parametrem result */) ``` -Response properties: -- `response.status` -- HTTP code of the response, -- `response.ok` -- `true` is the status is 200-299. -- `response.headers` -- Map-like object with HTTP headers. +Właściwości żądania: +- `response.status` -- kod odpowiedzi HTTP, +- `response.ok` -- `true` jeżeli kod odpowiedzi to 200-299. +- `response.headers` -- obiekt podobny do typu Map z nagłówkami HTTP. -Methods to get response body: -- **`response.text()`** -- return the response as text, -- **`response.json()`** -- parse the response as JSON object, -- **`response.formData()`** -- return the response as `FormData` object (form/multipart encoding, see the next chapter), -- **`response.blob()`** -- return the response as [Blob](info:blob) (binary data with type), -- **`response.arrayBuffer()`** -- return the response as [ArrayBuffer](info:arraybuffer-binary-arrays) (low-level binary data), +Metody służące do przetwarzania ciała odpowiedzi: +- **`response.text()`** -- zwróć odpowiedź jako tekst, +- **`response.json()`** -- odczytaj odpowiedź jako obiekt JSON, +- **`response.formData()`** -- zwróć odpowiedź jako obiekt `FormData` (kodowanie form/multipart, zobacz następny rozdział), +- **`response.blob()`** -- zwróć odpowiedź jako [Blob](info:blob) (dane binarne z typem), +- **`response.arrayBuffer()`** -- zwróć odpowiedź jako [ArrayBuffer](info:arraybuffer-binary-arrays) (niskopoziomowa reprezentacja danych binarnych), -Fetch options so far: -- `method` -- HTTP-method, -- `headers` -- an object with request headers (not any header is allowed), -- `body` -- the data to send (request body) as `string`, `FormData`, `BufferSource`, `Blob` or `UrlSearchParams` object. +Poznane jak dotąd opcje metody `fetch`: +- `method` -- metoda żądania HTTP, +- `headers` -- obiekt z nagłówkami żądania (nie każdy dowolny nagłówek jest dozwolony), +- `body` -- dane do wysyłki (ciało żądania) jako `string`, `FormData`, `BufferSource`, `Blob` lub obiekt `UrlSearchParams`. -In the next chapters we'll see more options and use cases of `fetch`. +W następnych rozdziałach poznamy więcej opcji i przypadków użycia metody `fetch`. From 625b23f1878c05617b4d7550e4ad2bc312206df2 Mon Sep 17 00:00:00 2001 From: mitroc Date: Sat, 5 Oct 2019 23:24:03 +0200 Subject: [PATCH 07/12] Correct 'article.md' --- 5-network/01-fetch/article.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/5-network/01-fetch/article.md b/5-network/01-fetch/article.md index 6983abfb5..82cb7f80a 100644 --- a/5-network/01-fetch/article.md +++ b/5-network/01-fetch/article.md @@ -3,7 +3,7 @@ Ilekroć jest to potrzebne, JavaScript potrafi wykonywać żądania sieciowe do serwera i pobierać nowe informacje. -Można na przykład użyć zapytania sieciowego do: +Można na przykład użyć żądania sieciowego do: - złożenia zamówienia, - wyświetlenia informacji o użytkowniku, @@ -75,7 +75,7 @@ let url = 'https://api.github.com/repos/javascript-tutorial/en.javascript.info/c let response = await fetch(url); *!* -let commits = await response.json(); // read response body and parse as JSON +let commits = await response.json(); // odczytaj ciało odpowiedzi i zwróć jako JSON */!* alert(commits[0].author.login); @@ -236,7 +236,7 @@ W poniższym przykładzie mamy znacznik ``, który pozwala na rysowanie - + ``` -In this example, the server code is not presented, as it's beyound our scope. The server accepts the POST request and replies "User saved". +Kod serwera jest poza naszym zakresem zainteresowania, nie pokazujemy go zatem w tym przykładzie. W każdym razie serwer akceptuje żądanie POST i odpowiada "Zapisano użytkownika". -## FormData Methods +## Metody FormData -We can modify fields in `FormData` with methods: +Pola w `FormData` możemy zmieniać następującymi metodami: -- `formData.append(name, value)` - add a form field with the given `name` and `value`, -- `formData.append(name, blob, fileName)` - add a field as if it were ``, the third argument `fileName` sets file name (not form field name), as it it were a name of the file in user's filesystem, -- `formData.delete(name)` - remove the field with the given `name`, -- `formData.get(name)` - get the value of the field with the given `name`, -- `formData.has(name)` - if there exists a field with the given `name`, returns `true`, otherwise `false` +- `formData.append(name, value)` - dodaj pole formularza z podanymi `name` oraz `value`, +- `formData.append(name, blob, fileName)` - dodaj pole tak jakby było znacznikiem ``, trzeci argument `fileName` ustawia nazwę pliku (nie nazwę formularza), tak jakby była nazwą pliku w systemie plików użytkownika, +- `formData.delete(name)` - usuń pole `name`, +- `formData.get(name)` - pobierz wartość pola `name`, +- `formData.has(name)` - jeżeli istniej pole `name`, zwróć `true`, w innym przypadku zwróć `false` -A form is technically allowed to have many fields with the same `name`, so multiple calls to `append` add more same-named fields. +Formularz, technicznie rzecz ujmując, może mieć wiele pól `name`, tak więc wiele wywołań metody `append` dodaje więcej pól o tej samej nazwie. -There's also method `set`, with the same syntax as `append`. The difference is that `.set` removes all fields with the given `name`, and then appends a new field. So it makes sure there's only field with such `name`, the rest is just like `append`: +Istnieje również metoda `set`, która ma taką samą składnię jak `append`. Różnica polega na tym, że `.set` usuwa wszystkie pola `name`, a następnie dodaje nowe pole. Dzięki temu upewnia się, że istnieje tylko jedno pole z podanym `name`. Pozostała część wygląda jak w metodzie `append`: - `formData.set(name, value)`, - `formData.set(name, blob, fileName)`. -Also we can iterate over formData fields using `for..of` loop: +Możemy również iterować po polach `formData` używając pętli `for..of`: ```js run let formData = new FormData(); formData.append('key1', 'value1'); formData.append('key2', 'value2'); -// List key/value pairs +// Wylicz pary klucz/wartość for(let [name, value] of formData) { - alert(`${name} = ${value}`); // key1=value1, then key2=value2 + alert(`${name} = ${value}`); // key1=value1 oraz key2=value2 } ``` -## Sending a form with a file +## Wysyłanie formularza z plikiem -The form is always sent as `Content-Type: form/multipart`, this encoding allows to send files. So, `` fields are sent also, similar to a usual form submission. +Formularz jest zawsze wysyłany jako `Content-Type: form/multipart`, gdyż takie kodowanie pozwala na wysyłkę plików. Tak więc pola `` są również wysyłane, podobnie jak to ma miejsce w zwykłym przesłaniu formularza. -Here's an example with such form: +Oto przykład takiego formularza: ```html run autorun
- + Picture:
@@ -110,21 +110,21 @@ Here's an example with such form: ``` -## Sending a form with Blob data +## Wysyłanie formularza z danymi typu Blob -As we've seen in the chapter , it's easy to send dynamically generated binary data e.g. an image, as `Blob`. We can supply it directly as `fetch` parameter `body`. +W rozdziale widzieliśmy, że wysyłka dynamicznie generowanych danych binarnych, np. obrazu jako `Blob`, jest dość prosta. Możemy go umieścić jako parametr `body` w metodzie `fetch`. -In practice though, it's often convenient to send an image not separately, but as a part of the form, with additional fields, such as "name" and other metadata. +W praktyce jednak często wygodniej jest wysłać obraz nie osobno, ale jako część formularza, z dodatkowymi polami, takimi jak "nazwa” i inne metadane. -Also, servers are usually more suited to accept multipart-encoded forms, rather than raw binary data. +Ponadto serwery są zwykle bardziej przystosowane do akceptowania formularzy zakodowanych w postaci wieloczęściowej niż surowych danych binarnych. -This example submits an image from ``, along with some other fields, as a form, using `FormData`: +W tym przykładzie pobieramy jako formularz obraz ze znacznika ``, wraz z innymi polami, używając `FormData`: ```html run autorun height="90" - + ``` -Kod serwera jest poza naszym zakresem zainteresowania, nie pokazujemy go zatem w tym przykładzie. W każdym razie serwer akceptuje żądanie POST i odpowiada "Zapisano użytkownika". +Kod serwera jest poza naszym zakresem zainteresowania, nie pokazujemy go zatem w tym przykładzie. W każdym razie serwer akceptuje żądanie POST i odpowiada "Użytkownik zapisany". ## Metody FormData From c178a4158790c4d20f82b3d7c300233a8e66267b Mon Sep 17 00:00:00 2001 From: mitroc Date: Sun, 6 Oct 2019 01:30:35 +0200 Subject: [PATCH 10/12] Translate 'server.js' --- 5-network/02-formdata/post.view/server.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/5-network/02-formdata/post.view/server.js b/5-network/02-formdata/post.view/server.js index a335b07b1..5b0483118 100644 --- a/5-network/02-formdata/post.view/server.js +++ b/5-network/02-formdata/post.view/server.js @@ -9,7 +9,7 @@ let router = new Router(); router.post('/user', async (ctx) => { ctx.body = { - message: "User saved" + message: "Użytkownik zapisany" }; }); @@ -34,7 +34,7 @@ router.post('/image-form', async (ctx) => { }); ctx.body = { - message: `Image saved, firstName: ${fields.firstName}, Image size:${files[0].length}, fileName: ${files[0].filename}` + message: `Obraz zapisany, imię: ${fields.firstName}, rozmiar obrazu:${files[0].length}, nazwa pliku: ${files[0].filename}.` }; }); @@ -61,7 +61,7 @@ router.post('/user-avatar', async (ctx) => { }); ctx.body = { - message: `User with picture, firstName: ${fields.firstName}, picture size:${files[0].length}` + message: `Użytkownik ze zdjęciem, imię: ${fields.firstName}, rozmiar obrazu:${files[0].length}.` }; }); From 3b71594a9b5bd703a9b751941f28a1f08fc1e2c8 Mon Sep 17 00:00:00 2001 From: mitroc Date: Tue, 8 Oct 2019 11:35:36 +0200 Subject: [PATCH 11/12] Apply suggestions from code review Co-Authored-By: Jakub Drozdek <30927218+jakubdrozdek@users.noreply.github.com> --- .../01-fetch/01-fetch-users/_js.view/test.js | 2 +- 5-network/01-fetch/01-fetch-users/solution.md | 4 +- 5-network/01-fetch/01-fetch-users/task.md | 8 ++-- 5-network/01-fetch/article.md | 38 +++++++++--------- 5-network/02-formdata/article.md | 40 +++++++++---------- 5 files changed, 46 insertions(+), 46 deletions(-) diff --git a/5-network/01-fetch/01-fetch-users/_js.view/test.js b/5-network/01-fetch/01-fetch-users/_js.view/test.js index ed8d03137..f32a5d4b3 100644 --- a/5-network/01-fetch/01-fetch-users/_js.view/test.js +++ b/5-network/01-fetch/01-fetch-users/_js.view/test.js @@ -1,7 +1,7 @@ describe("getUsers", function() { it("pobiera użytkowników GitHuba", async function() { - let users = await getUsers(['iliakan', 'remy', 'brak.użytkowników']); + let users = await getUsers(['iliakan', 'remy', 'nieistniejący.użytkownik']); assert.equal(users[0].login, 'iliakan'); assert.equal(users[1].login, 'remy'); assert.equal(users[2], null); diff --git a/5-network/01-fetch/01-fetch-users/solution.md b/5-network/01-fetch/01-fetch-users/solution.md index 8afaa86cd..369e34fbe 100644 --- a/5-network/01-fetch/01-fetch-users/solution.md +++ b/5-network/01-fetch/01-fetch-users/solution.md @@ -1,5 +1,5 @@ -Aby pobrać użytkownika wykorzystamy: `fetch('https://api.github.com/users/USERNAME')`. +Do pobrania użytkownika wykorzystamy: `fetch('https://api.github.com/users/USERNAME')`. Jeżeli odpowiedź zostanie zwrócona ze statusem `200`, wywołamy metodę `.json()`, aby móc odczytać javascriptowy obiekt. @@ -37,4 +37,4 @@ Zauważ, że metoda `.then` jest dołączona bezpośrednio do `fetch`, więc nie Gdybyśmy jednak użyli `await Promise.all(names.map(name => fetch(...)))` i wywołali metodę `.json()` dopiero na rezultacie, wówczas musiałaby ona czekać, aż wszystkie żądania zwrócą swoje odpowiedzi. Dołączając `.json()` bezpośrednio do każdego zapytania `fetch` możemy być pewni, że pojedyncze zapytania zaczną odczytywać dane jako JSON, bez czekania nawzajem na siebie. -Jest to przykład tego, jak przydatne może być niskopoziomowe Promise API, nawet jeżeli głównie korzystamy z `async/await`. \ No newline at end of file +Jest to przykład tego, jak przydatne może być niskopoziomowe Promise API, nawet jeżeli głównie korzystamy z `async/await`. diff --git a/5-network/01-fetch/01-fetch-users/task.md b/5-network/01-fetch/01-fetch-users/task.md index b4ea5f2d4..862ef551e 100644 --- a/5-network/01-fetch/01-fetch-users/task.md +++ b/5-network/01-fetch/01-fetch-users/task.md @@ -1,13 +1,13 @@ # Pobierz użytkowników z GitHuba -Stwórz asynchroniczną funkcję `getUsers(names)`, która pobiera z GitHuba tablicę z nazwami użytkowników, a następnie zwraca tablicę z odpowiadającymi im użytkownikami. +Stwórz asynchroniczną funkcję `getUsers(names)`, która otrzymuje tablicę z loginami do GitHuba, a następnie zwraca tablicę z odpowiadającymi im użytkownikami. -Informacje o użytkowniku przypisanym do `USERNAME`, znajdują się pod adresem url: `https://api.github.com/users/USERNAME`. +Informacje o użytkowniku przypisanym do `USERNAME`, znajdują się pod adresem: `https://api.github.com/users/USERNAME`. -W środowisku izolowanym znajduje się przykład testowy. +W naszym środowisku izolowanym znajduje się przykład testowy. Ważne informacje: 1. Można wykonać tylko jedno żądanie `fetch` o dane użytkownika. 2. Żądania nie powinny na siebie oczekiwać. Chodzi o to, aby dane dotarły jak najszybciej. -3. Jeżeli żądanie się nie powiedzie lub nie będzie użytkownika o podanej nazwie, funkcja powinna zwrócić `null` w tablicy wynikowej. \ No newline at end of file +3. Jeżeli żądanie się nie powiedzie lub nie będzie użytkownika o podanej nazwie, funkcja powinna zwrócić `null` w tablicy wynikowej. diff --git a/5-network/01-fetch/article.md b/5-network/01-fetch/article.md index 82cb7f80a..f564d6a40 100644 --- a/5-network/01-fetch/article.md +++ b/5-network/01-fetch/article.md @@ -12,11 +12,11 @@ Można na przykład użyć żądania sieciowego do: ...I to wszystko bez przeładowania strony! -Istnieje nadrzędny termin "AJAX" (skrót od Asynchronous JavaScript And XML) dotyczący żądań sieciowych w JavaScript. Nie musimy jednak używać XML-a: skrót ten pochodzi z dawnych czasów, stąd też zawiera takie właśnie słowo. Być może znasz już ten termin. +Istnieje nadrzędny termin "AJAX" (skrót od Asynchronous JavaScript And XML) dotyczący żądań sieciowych w JavaScripcie. Nie musimy jednak używać XML-a: skrót ten pochodzi z dawnych czasów, stąd też zawiera takie właśnie słowo. Być może znasz już ten termin. Istnieje wiele sposobów wysłania żądania sieciowego i pobrania informacji z serwera. -Metoda `fetch()` jest nowoczesna i wszechstronna, zaczniemy więc od niej. Nie jest ona wspierana przez stare przeglądarki (można ją zaimplementować skryptem typu polyfill), jest natomiast bardzo dobrze obsługiwana przez współczesne przeglądarki. +Metoda `fetch()` jest nowoczesna i wszechstronna, dlatego od niej zaczniemy. Nie jest ona wspierana przez stare przeglądarki (można ją dodać poprzez odpowiednią łatkę - ang. *polyfill*), jest natomiast bardzo dobrze obsługiwana przez współczesne przeglądarki. Podstawowa składnia jest następująca: @@ -29,15 +29,15 @@ let promise = fetch(url, [options]) Bez `options` mamy do czynienia ze zwykłym zapytaniem GET, pobierającym zawartość adresu `url`. -Przeglądarka natychmiast uruchamia zapytanie i zwraca obietnicę (ang. *promise*), której kod (wywołujący owo zapytanie) powinien użyć do uzyskania wyniku. +Przeglądarka natychmiast uruchamia zapytanie i zwraca obietnicę (ang. *promise*), której kod wywołujący powinien użyć do uzyskania wyniku. Uzyskanie odpowiedzi jest zwykle procesem dwuetapowym. -**Po pierwsze `obietnica`, zwrócona przez `fetch`, rozwiązuje się za pomocą obiektu wbudowanej klasy [Response](https://fetch.spec.whatwg.org/#response-class) , gdy tylko serwer odpowie nagłówkami.** +**Po pierwsze, obietnica `promise` zwrócona przez `fetch`, rozwiązuje się (ang. *resolves*) do obiektu wbudowanej klasy [Response](https://fetch.spec.whatwg.org/#response-class) , gdy tylko serwer odpowie nagłówkami.** -Na tym etapie możemy sprawdzić status HTTP, aby zobaczyć czy zapytanie się powiodło czy nie, możemy również sprawdzić nagłówki, ale jeszcze nie mamy dostępu do ciała odpowiedzi. +Na tym etapie możemy sprawdzić status żądania HTTP, aby dowiedzieć się, czy się ono powiodło, albo przejrzeć nagłówki. Nie mamy jednak jeszcze dostępu do ciała odpowiedzi. -Obietnica zostaje odrzucona jeżeli `fetch` nie był w stanie wykonać zapytania HTTP, np. ze względu problemy sieciowe lub brak strony, do której skierowano zapytanie. Nieprawidłowe statusy HTTP takie jak 404 lub 500 nie powodują błędu. +Obietnica jest odrzucana (ang. *rejects*), jeżeli `fetch` jest w stanie wykonać zapytania HTTP, np. ze względu na problemy sieciowe lub brak strony, do której skierowano zapytanie. Nieprawidłowe statusy HTTP, takie jak 404 lub 500, nie powodują błędu. Informację o statusie HTTP znajdziemy wśród właściwości odpowiedzi: @@ -50,23 +50,23 @@ Przykładowo: let response = await fetch(url); if (response.ok) { // jeżeli kod odpowiedzi HTTP jest z zakresu 200-299 - // pobierz ciało odpowiedzi (wyjaśnienie metody poniżej) + // pobierz ciało odpowiedzi (wyjaśnione poniżej) let json = await response.json(); } else { alert("Błąd HTTP: " + response.status); } ``` -**Po drugie, aby pobrać ciało odpowiedzi należy wywołać kolejną metodę.** +**Po drugie, aby pobrać ciało odpowiedzi, należy wywołać kolejną metodę.** -`Response` (pol. *odpowiedź*) zapewnia wiele metod, bazujących na obietnicach, które pozwalają na dostęp do ciała odpowiedzi i zwrócenie go w różnych formach: +Obiekt klasy `Response` (pol. *odpowiedź*) zapewnia wiele metod bazujących na obietnicach, które pozwalają na dostęp do ciała odpowiedzi i zwrócenie go w różnych formach: - **`response.text()`** -- odczytaj odpowiedź i zwróć jako tekst, - **`response.json()`** -- odczytaj odpowiedź i zwróć jako JSON, - **`response.formData()`** -- zwróć odpowiedź jako obiekt typu `FormData` (wyjaśnienie w [następnym rozdziale](info:formdata)), - **`response.blob()`** -- zwróć odpowiedź jako [Blob](info:blob) (dane binarne z typem), - **`response.arrayBuffer()`** -- zwróć odpowiedź jako [ArrayBuffer](info:arraybuffer-binary-arrays) (niskopoziomowa reprezentacja danych binarnych), -- ponadto `response.body` jest sam w sobie obiektem typu [ReadableStream](https://streams.spec.whatwg.org/#rs-class), co pozwala na odczytywanie go kawałek po kawałku, co zostanie pokazane w kolejnym przykładzie. +- ponadto `response.body` jest sam w sobie obiektem typu [ReadableStream](https://streams.spec.whatwg.org/#rs-class), co pozwala na odczytywanie go kawałek po kawałku. Ale o tym nieco później. Pobierzmy dla przykładu obiekt JSON z ostatnimi commitami z GitHuba. @@ -162,7 +162,7 @@ let response = fetch(protectedUrl, { }); ``` -... Istnieją również [zabronione nagłówki HTTP](https://fetch.spec.whatwg.org/#forbidden-header-name), których nie możemy zdefiniować: +... Istnieją również [zabronione nagłówki HTTP](https://fetch.spec.whatwg.org/#forbidden-header-name), których nie możemy ustawić: - `Accept-Charset`, `Accept-Encoding` - `Access-Control-Request-Headers` @@ -189,7 +189,7 @@ Dzięki nim protokół HTTP działa prawidłowo i jest bezpieczny, dlatego też ## Żądania POST -Ażeby wykonać żądanie typu `POST` lub jakiekolwiek inne żądanie sieciowe musimy użyć opcji dostępnych w metodzie `fetch`: +Do wykonania żądania z metodą `POST` lub jakąkolwiek inną musimy użyć opcji dostępnych w funkcji `fetch`: - **`method`** -- metoda HTTP, np. `POST`, - **`body`** -- ciało żądania, może przyjąć formę: @@ -222,13 +222,13 @@ let result = await response.json(); alert(result.message); ``` -Należy pamiętać, że jeżeli ciało żądania (`body`) jest łańcuchem znaków, wówczas nagłówek `Content-Type` domyślnie ustawiony jest jako `text/plain;charset=UTF-8`. +Należy pamiętać, że jeżeli ciało żądania (`body`) jest łańcuchem znaków, wówczas nagłówek `Content-Type` domyślnie ustawiony jest na `text/plain;charset=UTF-8`. -Ponieważ jednak zamierzamy wysłać obiekt JSON, użyjemy obiektu `headers` do ustawienia nagłówka `Content-Type` jako `application/json`, czyli właściwego dla danych zakodowanych w formacie JSON. +Ponieważ jednak zamierzamy wysłać obiekt JSON, użyjemy obiektu `headers` do ustawienia nagłówka `Content-Type` na `application/json`, czyli właściwego dla danych zakodowanych w formacie JSON. ## Wysyłanie obrazu -Możemy także za pomocą `fetch`przesłać dane binarne, używając obiektów `Blob` albo `BufferSource`. +Za pomocą `fetch` możemy także przesłać dane binarne, używając obiektów `Blob` albo `BufferSource`. W poniższym przykładzie mamy znacznik ``, który pozwala na rysowanie poprzez poruszanie nad nim myszką. Kliknięcie na przycisk "Prześlij" wysyła obraz do serwera: @@ -263,7 +263,7 @@ W poniższym przykładzie mamy znacznik ``, który pozwala na rysowanie Zauważ, że nie ustawiamy ręcznie nagłówka `Content-Type`, ponieważ obiekt `Blob` posiada wbudowany typ (tutaj `image/png`, wymuszony przez metodę `toBlob`). Dla obiektów `Blob` ten typ zostaje ustawiony dla nagłówka `Content-Type`. -Funkcję `submit()` można również przepisać nie używając składni `async/await` w taki sposób: +Funkcję `submit()` można również przepisać z pominięciem składni `async/await` w taki sposób: ```js function submit() { @@ -280,10 +280,10 @@ function submit() { ## Podsumowanie -Typowe żądanie sieciowe składa się z dwóch wywołań metody `await`: +Typowe żądanie sieciowe składa się z dwóch wywołań `await`: ```js -let response = await fetch(url, options); // rozwiązuje się z nagłówkami odpowiedzi +let response = await fetch(url, options); // rozwiązuje się do obiektu z nagłówkami odpowiedzi let result = await response.json(); // odczytuje ciało jako JSON ``` @@ -297,7 +297,7 @@ fetch(url, options) Właściwości żądania: - `response.status` -- kod odpowiedzi HTTP, -- `response.ok` -- `true` jeżeli kod odpowiedzi to 200-299. +- `response.ok` -- `true` dla kodów odpowiedzi z przedziału 200-299. - `response.headers` -- obiekt podobny do typu Map z nagłówkami HTTP. Metody służące do przetwarzania ciała odpowiedzi: diff --git a/5-network/02-formdata/article.md b/5-network/02-formdata/article.md index 1e054a56a..1e698e18c 100644 --- a/5-network/02-formdata/article.md +++ b/5-network/02-formdata/article.md @@ -3,7 +3,7 @@ W niniejszym rozdziale omówimy wysyłkę formularzy HTML: z plikami lub bez, z dodatkowymi polami i tak dalej. -Pomoże nam w tym obiekt typu [FormData](https://xhr.spec.whatwg.org/#interface-formdata). Jak zapewne się domyślasz jest to obiekt reprezentujący dane formularza HTML. +Pomoże nam w tym obiekt typu [FormData](https://xhr.spec.whatwg.org/#interface-formdata). Jak zapewne się domyślasz, jest to obiekt reprezentujący dane formularza HTML. Konstruktor wygląda następująco: ```js @@ -14,7 +14,7 @@ Przechwyci on automatycznie wszystkie pola formularza HTML na stronie. `FormData` posiada tę szczególną cechę, że metody sieciowe takie jak `fetch` mogą przyjmować obiekt `FormData` jako ciało. Jest on wówczas kodowany i wysyłany jako `Content-Type: form/multipart`. -Od strony serwera wygląda to jak zwykłe przesłanie formularza. +Z perspektywy serwera wygląda to jak zwykłe przesłanie formularza. ## Wysyłanie prostego formularza @@ -47,26 +47,26 @@ Jak widać, to niemal jedna linijka: ``` -Kod serwera jest poza naszym zakresem zainteresowania, nie pokazujemy go zatem w tym przykładzie. W każdym razie serwer akceptuje żądanie POST i odpowiada "Użytkownik zapisany". +Kod serwera jest poza naszym zakresem zainteresowania, zatem nie pokazujemy go w tym przykładzie. W każdym razie serwer akceptuje żądanie POST i odpowiada komunikatem: "Użytkownik zapisany". ## Metody FormData Pola w `FormData` możemy zmieniać następującymi metodami: -- `formData.append(name, value)` - dodaj pole formularza z podanymi `name` oraz `value`, -- `formData.append(name, blob, fileName)` - dodaj pole tak jakby było znacznikiem ``, trzeci argument `fileName` ustawia nazwę pliku (nie nazwę formularza), tak jakby była nazwą pliku w systemie plików użytkownika, +- `formData.append(name, value)` - dodaj pole formularza o nazwie `name` i wartości `value`, +- `formData.append(name, blob, fileName)` - dodaj pole tak jakby było znacznikiem ``; trzeci argument `fileName` ustawia nazwę pliku (nie nazwę formularza), tak jakby była nazwą pliku w systemie plików użytkownika, - `formData.delete(name)` - usuń pole `name`, - `formData.get(name)` - pobierz wartość pola `name`, -- `formData.has(name)` - jeżeli istniej pole `name`, zwróć `true`, w innym przypadku zwróć `false` +- `formData.has(name)` - jeżeli istnieje pole `name`, zwróć `true`; w innym przypadku zwróć `false` -Formularz, technicznie rzecz ujmując, może mieć wiele pól `name`, tak więc wiele wywołań metody `append` dodaje więcej pól o tej samej nazwie. +Formularz, z technicznego punktu widzenia, może mieć pól o nazwie `name`, tak więc wiele wywołań metody `append` doda wiele pól o tej samej nazwie. -Istnieje również metoda `set`, która ma taką samą składnię jak `append`. Różnica polega na tym, że `.set` usuwa wszystkie pola `name`, a następnie dodaje nowe pole. Dzięki temu upewnia się, że istnieje tylko jedno pole z podanym `name`. Pozostała część wygląda jak w metodzie `append`: +Istnieje również metoda `set`, która ma taką samą składnię jak `append`. Różnica polega na tym, że `.set` usuwa wszystkie pola o nazwie `name`, a następnie dodaje nowe pole. Dzięki temu zapewnia, że istnieje tylko jedno pole o nazwie `name`. Pozostała część wygląda jak w metodzie `append`: - `formData.set(name, value)`, - `formData.set(name, blob, fileName)`. -Możemy również iterować po polach `formData` używając pętli `for..of`: +Możemy również iterować po polach `formData`, używając pętli `for..of`: ```js run let formData = new FormData(); @@ -75,20 +75,20 @@ formData.append('key2', 'value2'); // Wylicz pary klucz/wartość for(let [name, value] of formData) { - alert(`${name} = ${value}`); // key1=value1 oraz key2=value2 + alert(`${name}=${value}`); // key1=value1 oraz key2=value2 } ``` ## Wysyłanie formularza z plikiem -Formularz jest zawsze wysyłany jako `Content-Type: form/multipart`, gdyż takie kodowanie pozwala na wysyłkę plików. Tak więc pola `` są również wysyłane, podobnie jak to ma miejsce w zwykłym przesłaniu formularza. +Formularz jest zawsze wysyłany jako `Content-Type: form/multipart`, gdyż takie kodowanie pozwala na wysyłkę plików. Tak więc pola `` są również wysyłane, podobnie jak ma to miejsce w zwykłym przesłaniu formularza. Oto przykład takiego formularza: ```html run autorun
- Picture: + Obraz:
@@ -112,13 +112,13 @@ Oto przykład takiego formularza: ## Wysyłanie formularza z danymi typu Blob -W rozdziale widzieliśmy, że wysyłka dynamicznie generowanych danych binarnych, np. obrazu jako `Blob`, jest dość prosta. Możemy go umieścić jako parametr `body` w metodzie `fetch`. +W rozdziale pt. "" widzieliśmy, że wysyłka dynamicznie generowanych danych binarnych, np. obrazu jako `Blob`, jest dość prosta. Możemy go umieścić jako parametr `body` funkcji `fetch`. W praktyce jednak często wygodniej jest wysłać obraz nie osobno, ale jako część formularza, z dodatkowymi polami, takimi jak "nazwa” i inne metadane. -Ponadto serwery są zwykle bardziej przystosowane do akceptowania formularzy zakodowanych w postaci wieloczęściowej niż surowych danych binarnych. +Ponadto serwery są zwykle lepiej przystosowane do akceptowania formularzy zakodowanych w postaci wieloczęściowej (ang. *multipart*) niż surowych danych binarnych. -W tym przykładzie pobieramy jako formularz obraz ze znacznika ``, wraz z innymi polami, używając `FormData`: +W tym przykładzie wysyłamy w formularzu obraz ze znacznika `` wraz z innymi polami, używając do tego `FormData`: ```html run autorun height="90" @@ -166,9 +166,9 @@ Serwer odczytuje dane formularza i plik, tak jakby było to zwykłe przesyłanie ## Podsumowanie -Obiekty typu [FormData](https://xhr.spec.whatwg.org/#interface-formdata) służą do przechwytywania formularza HTML i przesłania go za pomocą metody `fetch` lub innej metody sieciowej. +Obiekty klasy [FormData](https://xhr.spec.whatwg.org/#interface-formdata) służą do przechwycenia formularza HTML i przesłania go za pomocą `fetch` lub innej funkcji sieciowej. -Możemy albo utworzyć `new FormData(form)` z formularza HTML form, abo stworzyć obiekt bez formularza, a następnie dołączyć do niego pola metodami: +Możemy albo utworzyć `new FormData(form)` na podstawie formularza HTML, albo stworzyć obiekt bez formularza, a następnie dołączyć do niego pola metodami: - `formData.append(name, value)` - `formData.append(name, blob, fileName)` @@ -177,8 +177,8 @@ Możemy albo utworzyć `new FormData(form)` z formularza HTML form, abo stworzy Zwróćmy uwagę na dwie osobliwości: -1. Metoda `set` usuwa pole o tej samej nazwie, a `append` nie. To jedynia różnica między nimi. -2. Aby wysłać plik, potrzebna jest 3-argumentowa składnia, gdzie ostatnim argumentem jest nazwa pliku, która zwykle pobierana jest z systemu plików na potrzeby ``. +1. Metoda `set` usuwa zduplikowane pola o tej samej nazwie, a `append` nie. To jedynia różnica między nimi. +2. Aby wysłać plik, potrzebna jest trójargumentowa składnia, gdzie ostatnim argumentem jest nazwa pliku, zwykle pobierana z systemu plików na potrzeby ``. Inne metody to: @@ -186,4 +186,4 @@ Inne metody to: - `formData.get(name)` - `formData.has(name)` -I tak to wygląda! +I to by było na tyle! From c20bed7e158f31b607c19ab0ecca4c0f8fe88fed Mon Sep 17 00:00:00 2001 From: mitroc Date: Sun, 20 Oct 2019 15:03:49 +0200 Subject: [PATCH 12/12] Apply code review suggestions --- 5-network/01-fetch/article.md | 10 +++++----- 5-network/02-formdata/article.md | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/5-network/01-fetch/article.md b/5-network/01-fetch/article.md index f564d6a40..32eb82358 100644 --- a/5-network/01-fetch/article.md +++ b/5-network/01-fetch/article.md @@ -99,13 +99,13 @@ let text = await response.text(); // odczytaj ciało odpowiedzi jako tekst alert(text.slice(0, 80) + '...'); ``` -Aby zaprezentować odczyt danych w formacie binarnym, pobierzmy obraz logo [specyfikacji "fetch"](https://fetch.spec.whatwg.org) (patrz rozdział [Blob](info:blob) odnośnie operacji na obiekcie typu `Blob`): +Aby zaprezentować odczyt danych w formacie binarnym, pobierzmy obraz logo [specyfikacji "fetch"](https://fetch.spec.whatwg.org) (patrz rozdział [Blob](info:blob) odnośnie operacji na obiekcie `Blob`): ```js async run let response = await fetch('/article/fetch/logo-fetch.svg'); *!* -let blob = await response.blob(); // pobierz logo jako obiekt typu Blob +let blob = await response.blob(); // pobierz logo jako obiekt Blob */!* // stwórz dla niego znacznik @@ -261,7 +261,7 @@ W poniższym przykładzie mamy znacznik ``, który pozwala na rysowanie ``` -Zauważ, że nie ustawiamy ręcznie nagłówka `Content-Type`, ponieważ obiekt `Blob` posiada wbudowany typ (tutaj `image/png`, wymuszony przez metodę `toBlob`). Dla obiektów `Blob` ten typ zostaje ustawiony dla nagłówka `Content-Type`. +Zauważ, że nie ustawiamy ręcznie nagłówka `Content-Type`, ponieważ obiekt `Blob` posiada wbudowany typ (tutaj `image/png`, wymuszony przez metodę `toBlob`). Dla obiektów `Blob` ten typ jest przekazywany do nagłówka `Content-Type`. Funkcję `submit()` można również przepisać z pominięciem składni `async/await` w taki sposób: @@ -298,7 +298,7 @@ fetch(url, options) Właściwości żądania: - `response.status` -- kod odpowiedzi HTTP, - `response.ok` -- `true` dla kodów odpowiedzi z przedziału 200-299. -- `response.headers` -- obiekt podobny do typu Map z nagłówkami HTTP. +- `response.headers` -- z nagłówkami HTTP, podobny do Map. Metody służące do przetwarzania ciała odpowiedzi: - **`response.text()`** -- zwróć odpowiedź jako tekst, @@ -310,6 +310,6 @@ Metody służące do przetwarzania ciała odpowiedzi: Poznane jak dotąd opcje metody `fetch`: - `method` -- metoda żądania HTTP, - `headers` -- obiekt z nagłówkami żądania (nie każdy dowolny nagłówek jest dozwolony), -- `body` -- dane do wysyłki (ciało żądania) jako `string`, `FormData`, `BufferSource`, `Blob` lub obiekt `UrlSearchParams`. +- `body` -- dane do wysyłki (ciało żądania) jako `string` albo obiekt `FormData`, `BufferSource`, `Blob` lub `UrlSearchParams`. W następnych rozdziałach poznamy więcej opcji i przypadków użycia metody `fetch`. diff --git a/5-network/02-formdata/article.md b/5-network/02-formdata/article.md index 1e698e18c..41971479f 100644 --- a/5-network/02-formdata/article.md +++ b/5-network/02-formdata/article.md @@ -3,7 +3,7 @@ W niniejszym rozdziale omówimy wysyłkę formularzy HTML: z plikami lub bez, z dodatkowymi polami i tak dalej. -Pomoże nam w tym obiekt typu [FormData](https://xhr.spec.whatwg.org/#interface-formdata). Jak zapewne się domyślasz, jest to obiekt reprezentujący dane formularza HTML. +Pomoże nam w tym obiekt [FormData](https://xhr.spec.whatwg.org/#interface-formdata). Jak zapewne się domyślasz, jest to obiekt reprezentujący dane formularza HTML. Konstruktor wygląda następująco: ```js pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy