H. 1: REST API

1. Paigalda Node.js
2. Loo töölauale kaust restapi 
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`)
})

5. Käivita koodiredaktoris terminal ja seal järgnevad käsud:

npm init -y // package.json initsialiseerib node projekti
npm i express cors // kausta node_moodules installib express ja  cors paketti
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

Tee terminalis xh’ga POST päring vastu API-t, mis kustutab ühe vidina:

xh -v DELETE localhost:8080/widgets/2

H. 2: Loo Codesandbox-is HTML leht, mis kuvab auto andmeid

import "./styles.css";

const myJson = {
  Car0: {
    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 id="json">
    <h1>Car 0 properties</h1>
    <p>Color: ${myJson.Car0.Color}</p>
    <p>Tinted windows: ${myJson.Car0["Tinted windows"]}</p>
    <p>Wheels: ${myJson.Car0.Wheels}</p>
    <p>Roof cargo: ${myJson.Car0["Roof cargo"]}</p>
    <p>Audiosystem: ${myJson.Car0.Entertainment[0]}, ${myJson.Car0.Entertainment[1]}, ${myJson.Car0.Entertainment[2]}</p>
    <p>Accessories: ${myJson.Car0.Accessories[0]}, ${myJson.Car0.Accessories[1]}</p>
</div>`;

document.getElementById("app1").innerHTML = `
<div id="json">
    <h1>Car 1 properties</h1>
    <p>Color: ${myJson.Car1.Color}</p>
    <p>Tinted windows: ${myJson.Car1["Tinted windows"]}</p>
    <p>Wheels: ${myJson.Car1.Wheels}</p>
    <p>Roof cargo: ${myJson.Car1["Roof cargo"]}</p>
    <p>Audiosystem: ${myJson.Car1.Entertainment[0]}, ${myJson.Car1.Entertainment[1]}, ${myJson.Car1.Entertainment[2]}</p>
    <p>Accessories: ${myJson.Car1.Accessories[0]}, ${myJson.Car1.Accessories[1]}</p>
</div>`;

H. 3: SessionStorage

Kirjuta sessionStorage, sessionStorage.setItem(‘color’,’enda lemmikvärv’) ja sessionStorage.getItem(‘color’). Ning näed, et väljastatakse sessionStorage’ist sinu lemmikvärv.

Et näha, mis on Session Storage’isse salvestatud, mine Application>Session Storage>vastav domeen

Nüüd ava veel üks vahekaart ning mine samale lehele (chrome://newtab). Ava uuesti Application>Session Storage ning näed, et see on tühi.

H. 4: LocalStorage

Tee uus käsk localStorage.setItem('car','enda lemmikauto'). Selle käsuga lisati Local Storage’isse uued andmed.

H. 5: Küpsised

  1. Saada xh käsurearakendusega Twitteri veebiserverile päring ning vaata, millised küpsised Twitteri veebiserver tagasi annab. 
  2. Uuri netist set-cookie päise anatoomiat (MDN Web Docs saidil on päris hea kirjeldus) ning analüüsi, millist infot, kellele ja kui kauaks Twitter sinu brauserisse üritas sokutada.

H.6

Bacon API on naljakas ja kergekasutusega API, mis pakub erinevaid “bacon”-teemalisi andmeid ja pilte.

  1. Ava veebilehitsejas Code Sandbox sait
  2. Vali Official Templates alt static
  3. Kirjuta pildil olev kood index.html faili. Alustuseks kasuta HTML trafaretti (hüüumärk ja tab klahv).

H.7: Github andmete kasutamine API kaudu

H.8: XML faili kuvamine lehe

XML mängudega

H.10: Saada email Github push-imisel

H. 11: Vestlusruum serveri ja klientrakenduse vahel

index.html

<!doctype html>
<link rel="stylesheet" href="style.css">
<form name="publish">
 
    <input type="text" name="message" maxlength="50"/>
    <input type="submit" value="Send"/>
</form>
 
<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);
}

H.12: turvaline räsi

Tee uus fail nimega generateHash.js

Salasõnade hashimine on protsess, mille käigus salasõna teisendatakse kindla pikkusega tähemärkide (hash) unikaalseks kogumiks, kasutades selleks hash-funktsiooni.

Seletus:

  • Real 1 laaditakse sisse bcrypt-i, mida kasutatakse paroolide krüpteerimiseks
  • Real 5 loob funktsioon genSaltSync soola, mida kasutame real 10 räsi loomiseks. Funktsiooni sees parameeter rounds  (voorud) tähendab tegelikult kulutegurit. Kulutegur kontrollib, kui palju aega kulub ühe räsi arvutamiseks. Mida suurem on kulufaktor, seda rohkem on räsi voorusid. Vaikimisi on voorude arv 10, mis võtab kuskil 0,5 – 1 sekundit aega. Voorude arv 20 võib aga võtta juba ligi terve minuti aega.
  • Real 10 loob funktsioon hashSync räsi, koos soolaga (mille genereerisime real 5).

console.time ja console.timeEnd abil mõõdame funktsioonide aega. console.time ja console.timeEnd on paaris ning neil peab olema sama sisu (label), et leida üles paariline, kus algab või lõpeb aja mõõtmine.