Harjutused

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

Node.js

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

  1. Ava brauser ja mine chrome://newtab lehele.
  2. Ava konsool ning kirjuta konsoolile sessionStorage ning vajuta ENTER. Näed, et Session Storage on tühi.
  3. Tee uus käsk sessionStorage.setItem('color','enda lemmikvärv'). Selle käsuga lisati Session Storage’isse uued andmed
  4. 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

  1. Mine sellele vahekaardile tagasi, kus viimati sessionStorage käske sooritasid.
  2. Ava uuesti konsool ning kirjuta localStorage. Näed, et see on tühi.
  3. Tee uus käsk localStorage.setItem('car','enda lemmikauto'). Selle käsuga lisati Local Storage’isse uued andmed.
  4. 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.

  1. Ava veebilehitsejas Code Sandbox sait ja vali Static või HTML 5 Template
  2. Vali Official Templates alt static
  3. 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?

  1. Ava enda koodiredaktor
  2. Tee uus fail nimega generateHash.js
  3. 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');
  1. Paigaldada bcrypt käsuga npm install bcrypt
  2. Anna real 2 muutuja myPassword väärtuseks mingi tekst, mis on sinu parooliks
  3. Käivita fail parem hiireklõps faili sees ning Run ‘generateHash.js või kiirklahviga Ctrl + Shift + F10
  4. Muuda genSaltSync parameetris rounde ning vaata, mis juhtub

muutis soolakonstandi 30 peale ja sai teistsuguse tulemuse