ukryj menu
SPEC
aktualizacja: 2021-11-03 10:14:39
Uwaga: proszę zwracać uwagę w jaki sposób są przedstawione/sformatowane dane na skrinach z przeglądarki
1. kodowanie formularza i upload plików
defaultowo przy wysłaniu danych w url formularz kodowany (właściwość enctype) jest: application/x-wwwform-urlencoded
natomiast przy upload-zie plików należy podać, jak poniżej - multipart/form-data
2. klient - konstrukcja formularza
<form enctype="multipart/form-data" method="POST" action="/handleUpload">kopiuj
w formularzu przykładowe inputy:
date // data zdjęcia
text // nazwa zdjęcia
file // zdjęcie
<input type="file" required accept="image/*" name="imagetoupload"> kopiuj
3. server - upload z użyciem modułu formidable
najpierw zainstaluj formidable w wersji 1.2.2
npm install formidable@1.2.2kopiuj
potem na serwerze
var formidable = require('formidable');kopiuj
obsługa danych formularza przychodzących postem (inputy i pliki):
app.post('/handleUpload', function (req, res) {
let form = formidable({});
form.uploadDir = __dirname + '/static/upload/' // folder do zapisu zdjęcia
form.parse(req, function (err, fields, files) {
console.log("----- przesłane pola z formularza ------");
console.log(fields);
console.log("----- przesłane formularzem pliki ------");
console.log(files);
res.send("plik przesłany!")
});
});kopiuj
Zadanie 1: zwróć dane dokładnie w takiej formie jak na skrinie, testuj w chrome
4. rozszerzenia
domyślnie pliki zapisywane są bez rozszerzenia, aby to zmienić:
form.keepExtensions = true // zapis z rozszerzeniem plikukopiuj
Zadanie 2: zwróć dane dokładnie w takiej formie jak na skrinie, testuj w chrome
5. upload wielu plików
zmiana na kliencie
<input type="file" multiple required accept="image/*" name="imageupload">kopiuj
zmiana na serwerze
form.multiples = truekopiuj
5. upload wielu plików
zmiana na kliencie
<input type="file" multiple required accept="image/*" name="imageupload">kopiuj
zmiana na serwerze
form.multiples = truekopiuj
Zadanie 3 i 4: zwróć dane dokładnie w takiej formie jak na skrinie, testuj w chrome
Fetch, technologia komunikacji klient serwer, zastępująca Ajaxa
Fetch jest przygotowany do przesyłania danych w postaci JSON-a, można jednak za jego pomocą przesyłać też pliki.
W większości kolejnych zadań pojawia się też temat asynchronicznego wywoływania funkcji - async/await
7. Wysłanie danych post-em na serwer - fetch
klient
funkcja wywoływana kliknięciem butona
function fetchPost() {
const body = JSON.stringify({ a: 1, b: 2, c: "fetch" }) // body czyli przesyłane na serwer dane
const headers = { "Content-Type": "application/json" } // nagłowek czyli typ danych
fetch("/api", { method: "post", body, headers }) // fetch
.then(response => response.json())
.then(
data => console.log(data) // dane odpowiedzi z serwera
)
}kopiuj
wywołanie w onclick
document.getElementById("bt").onclick = function () {
fetchPost()
}kopiuj
serwer - odebranie i odesłanie danych
dane wysłane postem odbierzemy na serwerze Express z użyciem parsera jak na poprzednich zajeciach
console.log(req.body);
kopiuj
dane można wysłać też asynchronicznie, z użyciem pary async/await:
klient
async function fetchPostAsync() {
const body = JSON.stringify({ a: 3, b: 4, c: "fetch async" }) // body - dane
const headers = { "Content-Type": "application/json" } // nagłówek
let response = await fetch("/api", { method: "post", body, headers }) // fetch
if (!response.ok)
return response.status
else
return await response.json()
}kopiuj
Aby uniknąć kolejnych then(), jak w poprzednim przykładzie, wywołanie funkcji też musi być await
document.getElementById("bt").onclick = async function () {
let json = await fetchPostAsync()
console.log(json)
}kopiuj
powyższy kod sprzyja też rozdzieleniu funkcji od jej wykonania, np manipulacja interfejsem strony odbywa się teraz niezależnie od fetch-a
b) wylosowana cyfra po powrocie z serwera jest widoczna w konsoli przeglądarki
c) button "compare" wysyła na serwer cyfrę wybraną z selecta i wywołuje na serwerze funkcję porównującą wysłaną cyfrę i wylosowaną
6. fetch
Fetch, technologia komunikacji klient serwer, zastępująca Ajaxa
Fetch jest przygotowany do przesyłania danych w postaci JSON-a, można jednak za jego pomocą przesyłać też pliki.
W większości kolejnych zadań pojawia się też temat asynchronicznego wywoływania funkcji - async/await
7. Wysłanie danych post-em na serwer - fetch
klient
funkcja wywoływana kliknięciem butona
function fetchPost() {
const body = JSON.stringify({ a: 1, b: 2, c: "fetch" }) // body czyli przesyłane na serwer dane
const headers = { "Content-Type": "application/json" } // nagłowek czyli typ danych
fetch("/api", { method: "post", body, headers }) // fetch
.then(response => response.json())
.then(
data => console.log(data) // dane odpowiedzi z serwera
)
}kopiuj
wywołanie w onclick
document.getElementById("bt").onclick = function () {
fetchPost()
}kopiuj
serwer - odebranie i odesłanie danych
dane wysłane postem odbierzemy na serwerze Express z użyciem parsera jak na poprzednich zajeciach
console.log(req.body);
kopiuj
res.setHeader('content-type', 'application/json'); // nagłówek
res.end(JSON.stringify(req.body)); // odsyłamy dane do klienta w postaci stringakopiuj
res.end(JSON.stringify(req.body)); // odsyłamy dane do klienta w postaci stringakopiuj
dane można wysłać też asynchronicznie, z użyciem pary async/await:
klient
w poniższym kodzie funkcja musi być async, wewnątrz funkcji fetch musi być await
async function fetchPostAsync() {
const body = JSON.stringify({ a: 3, b: 4, c: "fetch async" }) // body - dane
const headers = { "Content-Type": "application/json" } // nagłówek
let response = await fetch("/api", { method: "post", body, headers }) // fetch
if (!response.ok)
return response.status
else
return await response.json()
}kopiuj
Zadaniem funkcji jest zwrocić odpowiedź z serwera, dlatego jest inaczej wywołana w kliku niż poprzednia
document.getElementById("bt").onclick = async function () {
let json = await fetchPostAsync()
console.log(json)
}kopiuj
powyższy kod sprzyja też rozdzieleniu funkcji od jej wykonania, np manipulacja interfejsem strony odbywa się teraz niezależnie od fetch-a
Zadanie 5: wykonaj jedno z zadań 5,6,7 z poprzedniej lekcji, używając fetcha zamiast Ajaxa
8. pobranie danych json z serwera
mamy dane w pliku json na serwerze
[
{
"id": 1,
"car_name": "Honda",
"car_type": "CRV",
"car_year": 2003,
"hex_color": "#237701",
"damaged": true
},
{
"id": 2,
"car_name": "Honda",
"car_type": "Prelude",
"car_year": 1986,
"hex_color": "#f7f23d",
"damaged": false
},
{
"id": 3,
"car_name": "Mercedes-Benz",
"car_type": "Sprinter 2500",
"car_year": 2012,
"hex_color": "#721ac8",
"damaged": false
},
{
"id": 4,
"car_name": "Acura",
"car_type": "RSX",
"car_year": 2004,
"hex_color": "#dcbeb7",
"damaged": true
},
{
"id": 5,
"car_name": "Land Rover",
"car_type": "Range Rover Sport",
"car_year": 2010,
"hex_color": "#3e29b2",
"damaged": false
}
]kopiuj
klient
const headers = { "Content-Type": "application/json" }
fetch("/api", { method: "get", headers })
.then(response => response.json())
.then(
data => console.log(data)
)kopiuj
serwer
require danych json
var json = require("./data.json")kopiuj
w GET /api odsyłamy nasze dane json
res.setHeader('content-type', 'application/json'); // nagłówek
res.end(JSON.stringify(json));kopiuj
Uwaga: taką sama funkcjonalność jak powyżej zapewnia wbudowana w expressa funkcja res.json()
8. pobranie danych json z serwera
mamy dane w pliku json na serwerze
[
{
"id": 1,
"car_name": "Honda",
"car_type": "CRV",
"car_year": 2003,
"hex_color": "#237701",
"damaged": true
},
{
"id": 2,
"car_name": "Honda",
"car_type": "Prelude",
"car_year": 1986,
"hex_color": "#f7f23d",
"damaged": false
},
{
"id": 3,
"car_name": "Mercedes-Benz",
"car_type": "Sprinter 2500",
"car_year": 2012,
"hex_color": "#721ac8",
"damaged": false
},
{
"id": 4,
"car_name": "Acura",
"car_type": "RSX",
"car_year": 2004,
"hex_color": "#dcbeb7",
"damaged": true
},
{
"id": 5,
"car_name": "Land Rover",
"car_type": "Range Rover Sport",
"car_year": 2010,
"hex_color": "#3e29b2",
"damaged": false
}
]kopiuj
klient
const headers = { "Content-Type": "application/json" }
fetch("/api", { method: "get", headers })
.then(response => response.json())
.then(
data => console.log(data)
)kopiuj
serwer
require danych json
var json = require("./data.json")kopiuj
w GET /api odsyłamy nasze dane json
res.setHeader('content-type', 'application/json'); // nagłówek
res.end(JSON.stringify(json));kopiuj
Uwaga: taką sama funkcjonalność jak powyżej zapewnia wbudowana w expressa funkcja res.json()
res.json({a:1})kopiuj
9. fetch data - simple api
/
/all
/first
/hondakopiuj
dodaj na serwerze odpowiednie endpointy (get-y)
tym razem nie ma strony html tylko serwer i zwracane dane json w odppowiednich get-ach
10. redirect to car api
do poprzedniego ćwiczenia dodaj stronę cars.html, a na niej prosty routing
kierujący do odpowiednich get-ów na serwerze
11. post file to server by fetch
api fetch-a służy też do wysyłania plików, z użyciem obiektu klasy FormData
9. fetch data - simple api
dane json z poprzedniego zadania mają być czytane przy takich adresach w pasku przegladarki
/all
/first
/hondakopiuj
dodaj na serwerze odpowiednie endpointy (get-y)
tym razem nie ma strony html tylko serwer i zwracane dane json w odppowiednich get-ach
10. redirect to car api
do poprzedniego ćwiczenia dodaj stronę cars.html, a na niej prosty routing
kierujący do odpowiednich get-ów na serwerze
11. post file to server by fetch
api fetch-a służy też do wysyłania plików, z użyciem obiektu klasy FormData
zastępującej funkcjonalnie formularz
klient
var fd = new FormData()
fd.append("file", document.getElementById("fileInput").files[0]) // plik z inputa
const body = fd
const headers = { "Content-Type": "application/json" }
fetch("/api", { method: "post", body })
.then(response => response.json())
.then(data => console.log(data) // odesłane z serwera dane
.catch(error => console.log(error)) // ew błądkopiuj
serwer
moduł formidable działa jak w ćwiczeniach 1-4
zadanie - po uploadzie odeślij takie dane do klienta w formacie json i pokaż na tej samej stronie:
{
"title": "file uploaded!",
"fileName": "plik.png",
"date": "2021-02-11T09:46:58.391Z"
}kopiuj
12. get image by fetch - zadanie dodatkowe
html
klient
var fd = new FormData()
fd.append("file", document.getElementById("fileInput").files[0]) // plik z inputa
const body = fd
const headers = { "Content-Type": "application/json" }
fetch("/api", { method: "post", body })
.then(response => response.json())
.then(data => console.log(data) // odesłane z serwera dane
.catch(error => console.log(error)) // ew błądkopiuj
serwer
moduł formidable działa jak w ćwiczeniach 1-4
zadanie - po uploadzie odeślij takie dane do klienta w formacie json i pokaż na tej samej stronie:
{
"title": "file uploaded!",
"fileName": "plik.png",
"date": "2021-02-11T09:46:58.391Z"
}kopiuj
12. get image by fetch - zadanie dodatkowe
html
na początek ładuje się domyślny obrazek
serwer
13. random - post data to server by fetch, download image by fetch - zadanie dodatkowe
przebieg ćwiczenia:
<img src="default.gif" alt="image" id="img">kopiuj
js
dane pliku wracają w postaci tzw blob-a
przeczytamy go obiektem klasy FileReader()
który zwraca dane pliku w postaci stringa base64
warto wylogować i podejrzeć
fetch("/url",
{ mode: 'cors' })
.then(response => response.blob())
.then(blob => {
console.log(blob);
const reader = new FileReader();
reader.addEventListener("load", function () {
console.log(reader.result) // to jest plik obrazka w postaci stringa base64
document.getElementById("img").src = reader.result; // wyświetlenie image
}, false);
reader.readAsDataURL(blob); // tutaj reader zaczyna czytać plik, powyższy event load to koniec tego czytania
//
});
kopiuj
{ mode: 'cors' })
.then(response => response.blob())
.then(blob => {
console.log(blob);
const reader = new FileReader();
reader.addEventListener("load", function () {
console.log(reader.result) // to jest plik obrazka w postaci stringa base64
document.getElementById("img").src = reader.result; // wyświetlenie image
}, false);
reader.readAsDataURL(blob); // tutaj reader zaczyna czytać plik, powyższy event load to koniec tego czytania
//
});
kopiuj
serwer
zadanie - dodaj get-y na serwerze, który obsłuży trzy butony jak na obrazku
13. random - post data to server by fetch, download image by fetch - zadanie dodatkowe
przebieg ćwiczenia:
a) button "random" wywołuje na serwerze funkcję losującą cyfrę z przedziału 1-3
c) button "compare" wysyła na serwer cyfrę wybraną z selecta i wywołuje na serwerze funkcję porównującą wysłaną cyfrę i wylosowaną
d) wynik porównania wraca do klienta i jest widoczny w konsoli
e) jeśli wynik porównania jest == true, pobierany jest fetchem obrazek A, jeśli nie to B
e) jeśli wynik porównania jest == true, pobierany jest fetchem obrazek A, jeśli nie to B