Harjutus 1 API
1. Paigalda Node.js
2. Loo töölauale kaust rest-api
3. Käivita koodiredaktor (nt VS Code, WebStorm vms) ja ava see kaust projektina
4. Loo kausta fail index.js järgneva sisuga:
const express = require('express');
const cors = require('cors');
const app = express();
app.use(cors()); // Avoid CORS errors in browsers
app.use(express.json()) // Populate req.body
const widgets = [
{ id: 1, name: "Cizzbor", price: 29.99 },
{ id: 2, name: "Woowo", price: 26.99 },
{ id: 3, name: "Crazlinger", price: 59.99 },
]
app.get('/widgets', (req, res) => {
res.send(widgets)
})
app.get('/widgets/:id', (req, res) => {
if (typeof widgets[req.params.id - 1] === 'undefined') {
return res.status(404).send({ error: "Widget not found" })
}
res.send(widgets[req.params.id - 1])
})
app.post('/widgets', (req, res) => {
if (!req.body.name || !req.body.price) {
return res.status(400).send({ error: 'One or all params are missing' })
}
let newWidget = {
id: widgets.length + 1,
price: req.body.price,
name: req.body.name
}
widgets.push(newWidget)
res.status(201).location('localhost:8080/widgets/' + (widgets.length - 1)).send(
newWidget
)
})
app.listen(8080, () => {
console.log(`API up at: http://localhost:8080`)
})

Nüüd kirjutan cmd-s järgmise:
1. npm init -y // package.json initsialiseerib node projekti
2. npm i express cors // kausta node_moodules installib express ja cors paketti
3. node . //käivitab index.js faili




Tee PowetShell’is xh’ga GET päring vastu API-t
xh -v localhost:8080/widgets

Tee PowerShelli’is xh’ga GET päring vastu API-t, mis tagastab kõik vidinad
xh -v localhost:8080/widgets/1

Tee PowerShelli’is xh’ga POST päring vastu API-t, mis lisab uue vidina
xh -v localhost:8080/widgets name=Fozzockle price=39.99

Tee PowerShelli’is xh’ga POST päring vastu API-t, mis kustutab ühe vidina
xh -v DELETE localhost:8080/widgets/2

Harjutus 2 JSON
lisas teise auto ja lisateavet sellele kasutades JSON-i

const myjson = [
{
Car: {
Color: "Rose Red",
"Tinted Windows": false,
Wheels: 4,
"Roof Cargo": null,
Entertainment: [
"FM Radio",
"MP3, MP4 and MKV player",
"harman/kardon speakers",
],
Accessories: ["satnav", "cruise control"],
},
},
{
Car1: {
Color: "Navy Blue",
"Tinted Windows": true,
Wheels: 4,
"Roof Cargo": "Thule",
Entertainment: [
"FM Radio",
"Apple CarPlay/Android Auto",
"Bowers & Wilkins Premium Sound speakers",
],
Accessories: ["self drive system", "luggage cover"],
},
},
];
document.getElementById("app").innerHTML = `
<div>
<h1>Car 1 Properties</h1>
<p>Color: ${myjson[0].Car.Color}</p>
<p>Tinted windows: ${myjson[0].Car["Tinted Windows"]}</p>
<p>Wheels: ${myjson[0].Car.Wheels}</p>
<p>Roof cargo: ${myjson[0].Car["Roof Cargo"]}</p>
<p>Entertainment: ${myjson[0].Car.Entertainment.join(", ")}</p>
<p>Accessories: ${myjson[0].Car.Accessories.join(", ")}</p>
</div>
<div>
<h1>Car 2 Properties</h1>
<p>Color: ${myjson[1].Car1.Color}</p>
<p>Tinted windows: ${myjson[1].Car1["Tinted Windows"]}</p>
<p>Wheels: ${myjson[1].Car1.Wheels}</p>
<p>Roof cargo: ${myjson[1].Car1["Roof Cargo"]}</p>
<p>Entertainment: ${myjson[1].Car1.Entertainment.join(", ")}</p>
<p>Accessories: ${myjson[1].Car1.Accessories.join(", ")}</p>
</div>
`;
Harjutus 3 Session Storage
seansisalvestust kasutades lisasin uue kirje ja lugesin seda
- Ava brauser ja mine chrome://newtab lehele.
- Ava konsool ning kirjuta konsoolile
sessionStorage
ning vajuta ENTER. Näed, et Session Storage on tühi. - Tee uus käsk
sessionStorage.setItem('color','enda lemmikvärv')
. Selle käsuga lisati Session Storage’isse uued andmed - Kirjuta uus käsk
sessionStorage.getItem('color')
ning näed, et väljastatakse sessionStorage’ist sinu lemmikvärv.


Harjutus 4 Local Storage
kasutades kohalikku salvestusruumi, lisasin kirje ja lugesin seda, mis näitab, et seansi salvestusruum ja kohalik salvestusruum on jaotatud erinevalt
- Mine sellele vahekaardile tagasi, kus viimati sessionStorage käske sooritasid.
- Ava uuesti konsool ning kirjuta
localStorage
. Näed, et see on tühi. - Tee uus käsk
localStorage.setItem('car','enda lemmikauto')
. Selle käsuga lisati Local Storage’isse uued andmed. - Soorita käsk localStorage.getItem(car) ning näed, et localStoragesse väljastatakse sinu lemmikauto.



Harjutus 5 Küpsised
Saada xh
käsurearakendusega Twitteri veebiserverile päring ning vaata, millised küpsised Twitteri veebiserver tagasi annab.
esimene rida on käsu xh allalaadimiseks, teine on näide selle kasutamisest
iwr -useb https://raw.githubusercontent.com/ducaale/xh/master/install.ps1 | iex
xh -h https://www.twitter.com



Harjutus 6 peekon API kasutamine
Bacon Ipsum on tasuta API, mis genereerib juhuslikult kalatäideteksti (kohatäiteteksti), mis põhineb lihasõnadel, nagu “peekon”, “sink” jne. Seda kasutavad veebiarendajad ja disainerid veebisaitide ja rakenduste loomisel tekstiplokkide ajutiseks täitmiseks.

- Ava veebilehitsejas Code Sandbox sait ja vali Static või HTML 5 Template
- Vali Official Templates alt static
- Kirjuta pildil olev kood index.html faili. Alustuseks kasuta HTML trafaretti (hüüumärk ja tab klahv).

body {
font-family: Arial, sans-serif;
background-color: #f4f4f4;
color: #333;
text-align: center;
margin-top: 50px;
}
button {
background-color: #ff6347;
color: white;
padding: 10px 20px;
border: none;
border-radius: 5px;
cursor: pointer;
font-size: 16px;
transition: background-color 0.3s ease;
}
button:hover {
background-color: #ff4500;
}
p {
margin-top: 20px;
font-size: 18px;
text-align: left;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title>Bacon API</title>
<link rel="stylesheet" href="styles.css" />
</head>
<body>
<button type="button" onclick="loadDoc()">Request bacon</button>
<p id="demo"></p>
<script>
function loadDoc() {
const xhttp = new XMLHttpRequest(); // Loome uue XMLHttpRequest objekti
xhttp.onload = function () {
// Funktsioon, mis käivitatakse, kui päring on lõppenud
const response = JSON.parse(this.responseText); // Tõlgime vastuse JSON-iks
const listContainer = document.getElementById("demo"); // Leiame elemendi, kuhu sisu lisada
const ul = document.createElement("ul"); // Loome uue <ul> elemendi
response.forEach(function (item) {
// Lisame vastuse elemendid loeteluna
const li = document.createElement("li");
li.textContent = item; // Määrame <li> tekstiks vastuse sisu
ul.appendChild(li); // Lisame <li> loetelusse
});
listContainer.innerHTML = ""; // Tühjendame vana sisu
listContainer.appendChild(ul); // Lisame <ul> elemendi
};
xhttp.open("GET", "https://baconipsum.com/api/?type=all-meat"); // Avame GET päringu
xhttp.send(); // Saadame päringu
}
</script>
</body>
</html>
4. Lõpptulemuseks peaksid saama andmeid peekoni kohta
5. Salvesta fail CTRL + S
Harjutus 7 REST API andmete kasutamine
REST (Representational State Transfer) on arhitektuurimudel, mida kasutatakse veebiteenuste loomisel ja rakenduste vahelise suhtluse lihtsustamiseks
GitHubi ligipääsutoken (access token) on turvaline viis, kuidas autentida ja volitada rakendusi või teenuseid, et nad saaksid GitHubi API-le ligipääsu sinu kontole või organisatsiooni kontole. Tokenit kasutatakse API-päringute tegemiseks, et saada või muuta andmeid GitHubis, nagu näiteks luua ja hallata repoosid, jälgida probleeme, teha muudatusi failides jne.
See kood näitab, kuidas kasutada kasutajaandmete toomiseks JavaScripti ja GitHubi API-t.
Sammud:
Looge projekt Code Sandboxis, kasutades Vanilla JavaScripti.
Kasutajaprofiili andmete toomiseks esitage GitHubi API-le taotlus, kasutades toomisfunktsiooni.
Printige tulemus konsooli, et näha, millised andmed tagastatakse.
Eraldage peamised andmed, nagu kasutajanimi, ID, profiili link ja avalike hoidlate arv.
Lisage sisestusväli, kuhu saate sisestada oma GitHubi kasutajanime.
Looge funktsioon, mis esitab API-le päringu, kasutades sisestatud nime, ja kuvab lehel teabe.
Alumine rida: sisestage GitHubi kasutajanimi ja rakendus kuvab nende profiiliteavet.

import "./styles.css"; // Impordi stiilid välisest failist
// Muutujad profiiliandmete salvestamiseks
let profileName = "";
let profileId = "";
let profileLink = "";
let profileRepos = "";
let profilePicture = "";
// Asünkroonne funktsioon GitHubi profiiliandmete pärimiseks
async function fetchProfile(username) {
try {
// Tee päring GitHubi API-le profiiliandmete saamiseks
const response = await fetch(`https://api.github.com/users/${username}`);
// Muudame vastus JSON formaati
const data = await response.json();
// Uuendame muutujaid saadud andmetega
profileName = data.login;
profileId = data.id;
profileLink = data.html_url;
profileRepos = data.public_repos;
profilePicture = data.avatar_url;
// Kuvame uuendatud andmed lehel
renderPage();
} catch (error) {
// Käsitle päringu vigu
console.error("Viga profiili pärimisel:", error);
}
}
// Funktsioon lehe sisu kuvamiseks
function renderPage() {
// Uuenda elemendi sisu, mille id on "app"
document.getElementById("app").innerHTML = `
<div>
<h1>Github profiili vaatamine</h1>
<p>Palun sisesta profiilinimi: </p>
<input id="username-input" /> <!-- Sisendväli kasutajanime sisestamiseks -->
<div class="content">
<h1 id="name">Nimi: ${profileName}</h1>
<p id="id">Id: ${profileId}</p>
<p id="reports">Avalikud repod: ${profileRepos}</p>
<p id="profile-url">
Link: <a href="${profileLink}" target="_blank">/users/${profileName}</a>
<!-- Link kasutaja profiilile -->
</p>
<div id="profile-avatar">
<img src="${profilePicture}" alt="${profileName} profiilifoto laadimine...."
style="width: 100px; height: 100px; border-radius: 60%;" />
<!-- Kasutaja avatar -->
</div>
</div>
</div>
`;
// Lisame sündmuste töötleja sisendväljale
document
.getElementById("username-input")
.addEventListener("keyup", function (event) {
// Kontrolli, kas vajutati Enteri klahvi
if (event.key === "Enter") {
// Hangi kasutaja nimi sisendväljalt
const username = event.target.value;
// Kutsu välja profiili pärimise funktsioon
fetchProfile(username);
}
});
}
// Esmane lehe kuvamine
renderPage();
body {
background: linear-gradient(135deg, #000, #1a1a1a), url("clonnex.gif");
background-size: cover;
background-blend-mode: overlay;
color: #e0e0e0;
font-family: "Roboto", sans-serif;
margin: 0;
padding: 20px;
}
h1 {
color: #ff3399;
font-size: 36px;
font-weight: 700;
text-shadow: 2px 2px 5px rgba(255, 51, 102, 0.6);
margin-bottom: 15px;
letter-spacing: 1.5px;
}
p {
font-size: 20px;
line-height: 1.8;
margin: 0;
}
#json {
background: rgba(28, 28, 28, 0.9);
border-radius: 12px;
padding: 25px;
margin-bottom: 25px;
box-shadow: 0 6px 12px rgba(255, 0, 102, 0.4);
transition: transform 0.3s ease, box-shadow 0.3s ease;
}
#json:hover {
transform: translateY(-5px);
box-shadow: 0 8px 16px rgba(255, 0, 102, 0.6);
}
#json:last-child {
margin-bottom: 0;
}
Harjutus 8 XML faili kuvamine JS lehel
XML – Extensible Markup Language

index.mjs
function loadXMLDoc() {
let xmlhttp = new XMLHttpRequest(); //uus päring
xmlhttp.onreadystatechange = function () {
if (this.readyState === 4 && this.status === 200) {
//статус запроса выполнен
getGameDetails(this);
}
};
xmlhttp.open("GET", "src/games.xml", true); //ava xml fail
xmlhttp.send();
}
function getGameDetails(xml) {
//saame andmed xml failis
const xmlDoc = xml.responseXML;
let tableRows = "<tr><th>Title</th><th>Price</th><th>Platforms</th></tr>"; //on liisatud andmet tüübid
let gameElements = xmlDoc.getElementsByTagName("game"); //
for (let i = 0; i < gameElements.length; i++) {
tableRows += //tsüükli loomine
"<tr><td>" +
gameElements[i].getElementsByTagName("title")[0].childNodes[0].nodeValue +
"</td><td>" +
gameElements[i].getElementsByTagName("price")[0].childNodes[0].nodeValue +
"</td><td>";
let platforms = gameElements[i].getElementsByTagName("platform");
for (let j = 0; j < platforms.length; j++) {
//tsüükli loomine
tableRows += platforms[j].childNodes[0].nodeValue + "/";
}
tableRows += "</td></tr>";
}
document.getElementById("xmlTable").innerHTML = tableRows;
}
document.getElementById("app").innerHTML = `<table id="xmlTable"></table>`;
loadXMLDoc();
games.xml
<?xml version="1.0" encoding="UTF-8"?>
<gamelist>
<game>
<title lang="en">Hearthstone</title>
<price>Free</price>
<platforms>
<platform>PC</platform>
<platform>ios</platform>
</platforms>
</game>
<game>
<title lang="en">Minecraft</title>
<price>10.99</price>
<platforms>
<platform>xbox</platform>
<platform>pc</platform>
</platforms>
</game>
<game>
<title lang="en">Dota 2</title>
<price>life</price>
<platforms>
<platform>PC</platform>
<platform>android</platform>
</platforms>
</game>
</gamelist>
style.css
body {
font-family: sans-serif;
background-color: #1e1e1e;
color: #f5f5f5;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
}
table {
width: 80%;
border-collapse: collapse;
margin: 20px 0;
font-size: 18px;
min-width: 400px;
background-color: #333;
border-radius: 8px;
overflow: hidden;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.15);
}
th,
td {
padding: 12px 15px;
text-align: left;
}
th {
background-color: #444;
color: #ffffff;
}
tr {
border-bottom: 1px solid #444;
}
tr:nth-of-type(even) {
background-color: #2a2a2a;
}
tr:hover {
background-color: #444;
}
td {
color: #dcdcdc;
}
Harjutus 10 Saada email Github push-imisel
1. Looge tühi repo.
2. Kloonige see repo endale arvuti.
3. Loo repo kausta kaks kausta struktuuriga: “.github/workflows”
4. Loo workflows kausta YAML fail. Pane nimeks näiteks mail-on-push.yml.
5. Lugege Github Actions struktuurist YAML failide puhul siit: https://docs.github.com/en/actions/quickstart
6. Lisage dawidd6/action-send-mail Github e-maili saatja YAML faili:
name: Send email on push
on:
push:
branches:
- main # Kontrollib, kas push on tehtud 'main' harusse
jobs:
mail_on_push:
runs-on: ubuntu-latest
steps:
- name: Send mail
# kasutatakse GitHubi tegevust e-kirjade saatmiseks
uses: dawidd6/action-send-mail@v3
with:
# SMTP serveri aadress ja port Gmaili jaoks
server_address: smtp.gmail.com
server_port: 465
# kasutajanimi ja parool, mis on salvestatud GitHubi saladustesse
username: ${{ secrets.MAIL_USERNAME }}
password: ${{ secrets.MAIL_PASSWORD }}
subject: "Push Notification for ${{ github.repository }} on branch ${{ github.ref }}"
to: "miljukovad@gmail.com"
body: |
Tehti push järgmisele repositooriumile: ${{ github.repository }} harusse: ${{ github.ref }}.
**Detailid:**
- Commit: ${{ github.sha }}
- Commiti sõnum: ${{ github.event.head_commit.message }}
- Commiti autor: ${{ github.event.head_commit.author.name }} ({{ github.event.head_commit.author.email }})
- Pusher: ${{ github.event.pusher.name }}
- **Pushi kuupäev ja aeg**: ${{ github.event.head_commit.timestamp }}
Vaata commit'i GitHubis: [Commiti link](${{ github.event.head_commit.url }})
# saatja nimi, mis kuvatakse e-kirjas
from: Github Actions
Lisage nõuetele meili pealkiri koos sisuga, sõnum koos sisuga ja kellele see meil saadetakse
Lisage meili saatjale vajalikud nõuded:


Sain oma meilile teate, et tehti “push”.

Harjutus 11 WebSocket API
Martin Kemppiga ja Anton Buivoliga tegime WebSocketil ja Node’il põhineva vestlusrakenduse.
WebSocket API võimaldab kliendil luua kahepoolset („dupleks“) suhtlust serveriga.
Juhend
Looge kaust ja kolm faili: index.html, index.js, style.css
Pääsete sellele terminali kaudu ligi. Seejärel kirjutage npm init
index.html
<!doctype html>
<form name="publish">
<input type="text" name="message" maxlength="50"/>
<input type="submit" value="Send"/>
</form>
<link rel="stylesheet" href="style.css">
<div id="messages"></div>
<script>
let url = location.host == 'localhost' ?
'ws://localhost:8080/ws' : location.host == 'javascript.local' ?
`ws://javascript.local/article/websocket/chat/ws` : // dev integration with local site
`wss://javascript.info/article/websocket/chat/ws`; // prod integration with javascript.info
//loome objekti koos veebisoketiga
let socket = new WebSocket(url);
// sõnumi saatmine vormile
document.forms.publish.onsubmit = function() {
let outgoingMessage = this.message.value;
socket.send(outgoingMessage);
return false;
};
// töödelda sissetulevaid sõnumeid
socket.onmessage = function(event) {
let incomingMessage = event.data;
showMessage(incomingMessage);
};
//kui kasutaja on socket'i sulgenud, kirjutame sellest konsooli.
socket.onclose = event => console.log(`Closed ${event.code}`);
// Näita sõnumeid div#messages
function showMessage(message) {
let messageElem = document.createElement('div');
messageElem.textContent = message;
document.getElementById('messages').prepend(messageElem);}
</script>

index.js
//Node’i WebSocket’i sisaldamine.
const http = require('http');
const fs = require('fs');
const ws = require('ws');
//Serveri seadistamine
const wss = new ws.Server({ noServer: true });
function accept(req, res) {
if (req.url === '/ws' && req.headers.upgrade &&
req.headers.upgrade.toLowerCase() === 'websocket' &&
req.headers.connection.match(/\bupgrade\b/i)) {
wss.handleUpgrade(req, req.socket, Buffer.alloc(0), onSocketConnect);
} else if (req.url === '/') {
// Отправляем index.html
fs.createReadStream('./index.html').pipe(res);
} else {
// Страница не найдена
res.writeHead(404);
res.end();
}
}
//Ühenduse loomine
const clients = new Set();
function onSocketConnect(ws) {
clients.add(ws);
ws.on('message', function(message) {
message = message.slice(0, 50); // максимальная длина сообщения — 50 символов
for (let client of clients) {
client.send(message);
}
});
ws.on('close', function() {
log('connection closed');
clients.delete(ws);
});
}
//Teksti kuvamine
let log;
if (!module["parent"]) {
log = console.log;
http.createServer(accept).listen(8080);
} else {
log = function() {};
// log = console.log;
exports.accept = accept;
}

style.css
body {
font-family: Arial, sans-serif;
background-color: #f9f9f9;
margin: 0;
padding: 20px;
}
form {
margin-bottom: 20px;
}
input[type="text"] {
width: 70%;
padding: 8px;
font-size: 14px;
border: 1px solid #ccc;
border-radius: 4px;
}
input[type="submit"] {
padding: 8px 16px;
font-size: 14px;
background-color: #4CAF50;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
input[type="submit"]:hover {
background-color: #45a049;
}
#messages {
margin-top: 20px;
}
#messages div {
background-color: #e1f5fe;
padding: 10px;
margin-bottom: 10px;
border-radius: 4px;
box-shadow: 0 1px 2px rgba(0,0,0,0.1);
}

PowerShell
#lae alla WebSocket
npm install ws
#node js allalaadimine internetist
#Serveri käivitamine
node index.js

saatis sõnumi ja server vastas mulle

Harjutus 12: Kuidas genereerida turvaline räsi?
- Ava enda koodiredaktor
- Tee uus fail nimega
generateHash.js
- Lisa sinna järgnev kood:
const bcrypt = require('bcrypt');
const myPassword = '';
console.time('Time to generate salt');
const salt = bcrypt.genSaltSync(10);
console.log('This is your salt: ' + salt);
console.timeEnd('Time to generate salt');
console.time('Time to generate hash');
const hashedPassword = bcrypt.hashSync(myPassword, salt);
console.log(myPassword + ' is your password & this is your password after hashing it: ' + hashedPassword);
console.timeEnd('Time to generate hash');
- Paigaldada bcrypt käsuga
npm install bcrypt
- Anna real 2 muutuja
myPassword
väärtuseks mingi tekst, mis on sinu parooliks - Käivita fail parem hiireklõps faili sees ning Run ‘generateHash.js või kiirklahviga Ctrl + Shift + F10
- Muuda
genSaltSync
parameetris rounde ning vaata, mis juhtub

muutis soolakonstandi 30 peale ja sai teistsuguse tulemuse
