V dnešním díle nepravidelného cyklu se podíváme na to, jak v javě parsovat html stránku.
Spousta webů dneska se proti parsování snaží bránit. Různý redirecty, javascript a podobně.
Aby dokázal Java program si poradit i s takovými weby, musí si v principu zahrát na webový prohlížeč.
Na pomoc si vezmeme již vytvořenou knihovnu jsoup - https://jsoup.org/
Web obsahuje i cookbook, jak se s knihovnou pracuje.
S pomocí této knihovny je napsání parseru poměrně triviální záležitost.
Ukážeme si to na reálném webu - http://1url.cz/ptb6J, knihovna si poradí i s redirect, takže správně zpracovává až ov.ihned.cz
Jako první krok potřebujeme načíst stránku, to se provede:
// fetch URI and parse
Document doc = Jsoup.connect(url).get();
Hledáme na stránce tabulku, pro každý její řádek chceme vypsat IČO a datum.
// we are looking for a table
Elements tables = doc.select("table");
// there should be just one, but use foreach, just to be sure
for (Element table : tables) {
// need rows
Elements rows = table.select("tr");
for (Element row : rows) {
// need columns
Elements cols = row.select("td");
// basically, the first row will not have any td, skip
if (cols.size() > 2) {
// // needed there just to get URL, if wanted
// Element link = cols.get(0).select("a").first();
// control what will be printed. ICO, date
System.out.println(String.format("%s, %s", cols.get(2).text(), cols.get(4).text());
}
}
}
Fórko s tím vložením kódu pracuje úplně na nic, tak snad si to rozluštíte
V případě potřeby pro daný záznam máme připraven i link na samotný zápis, který by se zase otevřel a zpracoval.
Enjoy!
Určitě vždycky ošetřovat. Nedokážu si představit, jak by měla jakákoliv aplikace fungovat jen na základě ,,schování tlačítka".
To je jako neověřovat, jestli příspěvek, kterej upravuješ, je tvůj nebo ne.
Nehrab se v ovladačích, pokud to funguje. Maximálně stáhni nejnovější ovladače pro grafiku (z nvidia/amd.com). Zbytek ovladačů nech být, pokud to funguje/je to stabilní. Na USB/chipsetu/síťový kartě a já nevím na čem ještě, nemáš co vylepšovat, můžeš to akorát rozbít .
A platit za nějakej náhodnej vyhledávač, co instaluje bůh ví co... To určitě ne. Když už, tak si najdi stabilní verzi ovladačů z oficiálních stránek a neinstaluj náhodný verze, co najdeš na netu.
Hodně lidí v dnešní době si pořizuje PC jen na hraní her. Proto byste měli svoji pozornost při vybírání věnovat hlavně grafické kartě. Samozřejmě jsou i hry, které těží hlavně z výkonu CPU, patří mezi ně například CS:GO a celkově jejich Source Engine. Většina her, ale těží právě z grafické karty.
Hlouposti, na které narazíte:
Větší paměť = více výkonu
- ano, toto opravdu platí, ovšem pokud karta umí paměť využít a je možno ji využít -> vyšší rozlišení, vysoké nastavení textur.
Jsou karty (např. GT630), které disponují 4GB VRAM, ovšem jejich jádro je tak slabé, že je v životě nemůžou využít. Není vůbec určena na hraní, maximálně starších her. Je určena hlavně uživatelům, co sledují filmy, pracují v nenáročných programech atp.
AMD CPU = AMD GPU / Intel CPU = Nvidia GPU
- opravdu nemusíte používat tyto kombinace CPU a GK, jsou mezi sebou kompatibilní a nenesou vůbec žádné mínusy nebo problémy. Je úplně jedno jestli dáte Intel CPU, AMD GK, je to to stejné, jako dávat MSI GK do ASRock desky, ničemu to nevadí.
Nvidia má lepší grafiky / AMD má lepší grafiky
- o tomto se již šířilo mnoho debat, válek mezi uživateli obou výrobců. Realita je taková, že žádný z výrobců, není horší nebo lepší. Vždycky konkurence vydá stejně výkonnou kartu, aby mohla soupeřit s kartami toho druhého. Je pravda, že AMD má častěji vyšší spotřebu, to se ale s příchodem nových R9 NANO, Fury,... zlepšilo. Technologie má každý výrobce svoje, většina jsou si podobná, jen každá funguje ve svém teritoriu.
GDDR5 = Nekompatibilní s deskami s DDR3
- toto je samozřejmě nesmysl, je to podobné, jako u kombinace AMD/AMD, Intel/Nvidia. Karta má svoje paměti, deska má svoje paměti, na toto nemusíte brát vůbec ohled.
Výběr
Cena
Asi nejdůležitější věc, při výběru karty. Často nejdražší komponenta v sestavě. Rozdělit je můžeme do low-endu, mainstreamu a hi-end.
Pokud budeme počítat s PC na hry, nemá opravdu smysl kupovat karty pod 2500Kč, kde už se pohybují už jenom takové karty, které já nazývám jako "pouze zobrazovače plochy" (730 / 740 / 240).
Takové použitelnější už se jeví 750Ti / 260X po 1050 / 460 .
Mainstreamem se dnes již myslí R9 270X / 470 až po 290X / 1060 / 480 / 390X / Nano / 970 / 780Ti, pomalu už i 980 a 1070.
Hi-end samozřejmě 980Ti / Fury X / 1080 ....
Brát ohled musíme samozřejmě i na CPU, je zbytečné kupovat i7 k 270X a naopak 980 k i3.
Externí výrobci
Druhá věc, která bude rozhodovat při vašem výběru, bude od jakého výrobce, nemyslím tím už Nvidia nebo AMD, ale výrobce, kteří kartu upravují po svém - chladič, PCB, součástky, frekvence.
V ČR jsou obecně nejrozšířenější MSI, Gigabyte, ASUS, Sapphire, Evga.
Méně známí Palit, Gainward, Zotac, na bazarech někdy i Club3D.
Kvalitativně jsou na tom nejlépe MSI, Gigabyte, ASUS, Evga. Z těch výrobců, co u nás jsou špatně k sehnání je to např. Club3D, Zotac vyšší verze, Inno3D, KFA2. Bohužel u nás právě jen s dvouletou zárukou.
Dále se karty řadí do různých edic, od limitovaných až po stálé vyšší a nižší. Pokud chcete opravdu tu nejkvalitnější kartu od daných výrobců, jsou to např. tyto:
Tyto karty mají většinou pár věcí, které ulehčí taktování. Vždy mají lépe řešené chlazení, napájení a více součástek, které pomáhají stabilitě a vyššímu taktování.
Zdroj
Ovšem to nejhlavnější, podle čeho musíte kartu vybírat je - zdroj. Nejdůležitější komponenta v PC, s nekvalitním zdrojem, můžete přijít o jednu, ale také o všechny komponenty, pokud jeho ochrana selže.
U nás nejprodávanější kvalitní výrobce zdrojů, je bezpochyby Seasonic, již od OEM verzí až po jejich top edice se jedná o kvalitní zdroje s kvalitními součástkami, nižší verze sice nemají např. opletené kabely nebo mají vyšší zvlnění, ale velmi málo se stává, že by tento zdroj vyhořel a případně s sebou vzal jinou komponentu.
Další, kteří se řadí mezi ty kvalitnější, jsou např. Corsairy. Jejich řady RM a výše, jsou velmi kvalitní. Nejnižší řada, kterou poradím, jsou CXxxxM Buildery.
Celkem nedávno se u nás objevily zdroje od Evgy. Verze G2 a GS jsou to nejkvalitnější, co od těchto výrobců můžete pořídit a přitom stojí na svou kvalitu velmi málo. Po registraci do 14 dní od koupě na ně máte 10 let záruku a nabízí i semipasivní režim.
Většinou můžete v obchodech u karet napsáno "Doporučený výkon zdroje". Tyto hodnoty mohou být docela matoucí, u karet, které potřebují maximálně 250W najdete 600W zdroj, přitom celá sestava bude mít maximálně 500W. Je to hlavně z toho důvodu, když si někdo koupí 600W Zalman, který je rád za to, že se vůbec dostal na trh. Případně kdybyste vlastnili 200W AMD CPU .
Levné dostatečně kvalitní zdroje jsou ještě např. Fortron Hexa+ a Fortron Hyper.
Rada: Jestliže se rozmýšlíte mezi několika stejnými kartami (např. 4x 1060 atp.). Vyberte si tu nejlevnější nebo tu, která má u sebe nejvíce věcí navíc (bývají to myši, kódy na hry, podložky a jiné...), které můžete prodat. Důvod je jednoduchý, většinou se karty od různých výrobců za podobnou cenu liší jenom tím, jaké mají frekvence, ovšem těchto frekvencí můžete na 90% případů dosáhnout i sami (tento odstavec se netýká karet, které se liší použitým chladičem, tam už je pak rozdíl klidně znatelný - hlučnost, teploty, kvalita PCB a součástek).
Pokud vás napadá, co bych mohl doplnit nebo mám někde chyby, dejte prosím vědět.
Díky a přeju šťastný výběr.
Chtěl bych se podělit o zkušenosti s pastou Coollaboratory Liquid Ultra, dále jen CLU. Jelikož se této pasty každý bojí, protože je elektricky vodivá, trochu šikovnější člověk vlastně ani nemá čeho a výsledky jsou velmi pozitivní.
1) Balení
[zdroj: www.pc-max.de]
V balení najdete 2 štětečky, kterými pastu roztíráte, ubrousky na setření pasty a pastu samotnou. Jedno balení by mělo vystačit na 10 nanesení.
2) Vodivost a nanesení
Pasta je z tekutých slitin kovů, jak se dočtete ve všech obchodech. Samozřejmě je tu riziko, ale to byste museli být tak nešikovní a pastu napatlat i všude okolo CPU. Pokud vám "nekápne" na desku, tak prakticky nemáte šanci si něco zničit, protože štětečkem opravdu rozetřete jen tam, kam chcete.
Další důležitá věc je, že se pasta NESMÍ použít, pokud máte základnu chladiče z HLINÍKU. Na ten lze použít Coollaboratory Liquid Copper (vodivost je ale 90W vs 12W/mK).
Narozdíl od jiných past, se CLU roztírá po celém heatspreaderu CPU.
[zdroj: www.technic3d.com]
3) Teploty
Co by to bylo za recenzi, bez vyzkoušení. Porovnal jsem použití této pasty proti snad nejpoužívanější pastě u nás - MX-2.
Vodivost je 90W vs 9W/mK. CPU i7 4790k 4.4GHz, 4.4GHz Cache 1.25V a měřeno je to s vodním chlazením při velmi náročném benchmarku XTU na 30min.
Jak můžeme vidět, rozdíl teplot je viditelný, jak v idle, tak ve velmi vysoké zátěži.
Závěr: Rozhodně za mě doporučuji, pokud nejste gramla, nic nehrozí.
posledních pár let se věnuji JavaScriptu a konkrétně Node.js skoro rok. Předpokládám, že z mých dřívějších příspěvků na fóru již víte, co to Node.js je, takže to nemusím rozvádět.
Hned v počátku mého nástupu na Node.js jsem si vzal velký krajíc, obecně jako vždy když začínám něco nového, a pustil jsem se do tvorby webového frameworku. Webový framework na Node.js je něco co zatím ještě neexistuje nebo alespoň ne v takovém měřítku, jak klasické webové frameworky, například z PHP, vnímáme v dnešní době. To že žádný takový framework zatím ještě neexistuje je má motivace. Node.js je svým způsobem novinka. Spousta lidí říká, že Node.js není určený k tvorbě webových stránek. Ale proč k tomu není určený? No protože třeba pro PHP existuje spousta hotových frameworků a k nim spousta CMS, eshop systémů aj. Proč tedy dělat něco nového? Node.js pro to není určené, protože se to nikomu dělat nechce. Node.js je už spíše na úrovni C#, Javy a jiných nízkoúrovňových jazyků. Takže webový framework se na Node.js vytvoří asi stejně jako v C# nebo Javě. Vytvoříte Socket server, který poslouchá na nějakém portu, přijmete požadavek, uděláte nějakou magii a pošlete výsledek z5. Tak to prostě funguje, avšak s tím rozdílem, že Node.js má připravenou funkcionalitu k http komunikaci, takže vytvořit na něm webový framework bude o chlup jednodušší než třeba v holém C# či Javě.
Motivací pro tento seriál je právě rozšíření znalostí v oblasti Node.js, a tím podpoření mého frameworku. Název mého frameworku je Jumbo. Už teď je Jumbo schopný vytvořit plnohodnotné stránky stejně jednoduše jako to jde s Nette. Nette je mimo jiné předlohou Jumba, protože Nette je v česku široce rozšířený framework, a tak se s ním lidem bude lépe pracovat, když bude mít podobné konstrukce.
Co vše si tedy v seriálu řekneme/ukážeme?
V úvodu si společně zprovozníme Node.js a vytvoříme jednoduchou aplikaci, ke které budeme moci přistoupit z prohlížeče.
Malé opakování JS
Node.js je eventově řízený jazyk. To v podstatě znamená, že všechny akce - nebo alespoň většina - běží "asynchronně". Proto je Node.js plné callback funkcí bez kterých by to prostě nešlo.
Proto si v rámci opakování ukážeme práci s anonymními fcemi a práci s closure a scope.
A právě scope a closure jsou dle mého "dvě" věci, které dělají lidem v JS problém, proto ho moc lidí nevyužívá na programování, protože pochopení scope a closure v JS není jednoduché a je příčinou hodně problémů.
První ukážu kód a následně jej vysvětlím.
/**
* Proměnná definovaná v globálním scope
* @type {String}
*/
var globalniPromenna = "global";
var druhaGlobalniPromenna;
var tretiGlobalniPromenna;
(function () {
var prvniLokalniPromenna = "Ahoj ";
})();
(function () {
druhaGlobalniPromenna = ", Nazdar ";
})();
(function () {
tretiGlobalniPromenna = ", Zdravím ";
});
(function (param) {
var lokalniPromenna = ", Čau ";
/**
*
* @param {String} parametr
* @param {Function} callback
* @returns {String}
*/
var anonymniFunkce = function (parametr, callback) {
var prvniGlobalniPromenna = prvniGlobalniPromenna || "";
if (!callback) {
throw new Error("Nemáte nastaven callback");
}
if (typeof callback != "function") {
throw new Error("Callback není funkce");
}
setTimeout(function () {
if (parametr == "throw") {
throw new Error("Je libo nezachytitelnou vyjímku?");
}
if (parametr == "callback-error") {
callback(null, new Error("Tady máš ten svůj error, klidně si ho chyť."));
return;
}
callback(typeof parametr == "string" ? (globalniPromenna + " " + param + ": " + prvniGlobalniPromenna + druhaGlobalniPromenna + tretiGlobalniPromenna + lokalniPromenna + " | " + parametr).toUpperCase() : "Tak když mi nedáš data co chci, tak ti vrátím prd!");
}, 1000);
};
var result;
// Zavoláme se správným parametrem, ale bez callbacku
try {
result = anonymniFunkce("Test");
} catch (err) {
console.log("Špatné volání vrátilo: ", result);
console.log(err.message);
}
// Zavoláme se správným parametrem, ale se špatným callbackem
try {
result = anonymniFunkce("Test", "Zde má být callback fce, ne string");
} catch (err) {
console.log("Druhé špatné volání vrátilo: ", result);
console.log(err.message);
}
// Zavoláme se špatným parametrem
try {
result = anonymniFunkce(true, function (data) {
alert(data);
});
console.log("Třetí špatné volání vrátilo: ", result);
} catch (err) {
console.log(err.message);
}
// Konečně zavoláme správně
try {
var dalsiPromenna = "A výsledek je: ";
result = anonymniFunkce("Test", function (data) {
alert(dalsiPromenna + data);
});
console.log("Správné volání vrátilo: ", result);
} catch (err) {
console.log(err.message);
}
// Teď si zkusíme chytit asynchronní Error
try {
result = anonymniFunkce("throw", function (data) {
alert(dalsiPromenna + " | " + data);
});
console.log("Throw volání vrátilo: ", result);
} catch (err) {
console.log(err.message);
}
// Teď si zkusíme chytit callback Error
try {
result = anonymniFunkce("callback-error", function (data, err) {
if (err instanceof Error) {
console.log("Callback chyba: ", err.message);
return;
}
alert(dalsiPromenna + " | " + data);
});
console.log("Callback err volání vrátilo: ", result);
} catch (err) {
console.log(err.message);
}
})("pozdravy");
Tak script je delší než jsem původně plánoval, ale je to tak dobře. Script ukazuje práci se scope a closure a zároveň ukazuje fci callbacků a zachytávání chyb v Node.js.
Když se na script podíváte, uvidíte několik anonymních fcí a několik proměnných.
Dokážete si tipnout, jaké výsledné data vrátí callback správného volání?
Script si vyzkoušejte normálně v prohlížeči a podívejte se, co vrátí konzole.
tmp.html:48 Špatné volání vrátilo: undefined
tmp.html:49 Nemáte nastaven callback
tmp.html:57 Druhé špatné volání vrátilo: undefined
tmp.html:58 Callback není funkce
tmp.html:67 Třetí špatné volání vrátilo: undefined
tmp.html:81 Správné volání vrátilo: undefined
tmp.html:93 Throw volání vrátilo: undefined
tmp.html:110 Callback err volání vrátilo: undefined
tmp.html:29 Uncaught Error: Je libo nezachytitelnou vyjímku?(anonymous function) @ tmp.html:29
tmp.html:103 Callback chyba: Tady máš ten svůj error, klidně si ho chyť.
Všechny návratové hodnoty jsou undefined, protože volaná fce jednoduše nic nevrací. To co má fce vrátit, tak předává do callbacku jako parametr.
Vysvětlení scriptu
Ještě před vysvětlením scriptu vám ukážu jednoduché příklady na dílčí problémy
Scope a closure
Closure je zapouzdření, které vytvoříme pomocí function() {}
Vytvořením closure nám v podstatě vzniknou 2 scope, a to globální a lokální.
Proměnné, které jsou deklarovány uvnitř funkce jsou lokální a mimo tuto funkci nejsou viditelné.
Naopak vše co bylo vytvořeno nad function() {} je pro closure jeho globální scope.
Příklad
var opravduGlobalniPromenna = ", která je definovaná ve skutečném globálním scopu aplikace, není zapouzdřena žádnou fcí.";
// Vytvoříme closure; anonymní fci, kterou i ihned zavoláme
(function() {
var lokalniPromenna = "Lokální promenná pro toto closure";
var funkce = function() {
var dalsiLokalniPromenna = "Lokální promenná pro toto closure";
// dalsiLokalniPromenna je pro toto closure lokální proměnnou a localniPromenna je globální proměnnou společně s opravduGlobalniPromennou
// Zde jednoduše vidím vše co bylo definováno zde i dříve; Co však bylo definováno zde, není vidět venku
};
})();
Schválně jsem se díval ještě na internet, jak bych to mohl pěkně vysvětlit a líbil se mi příklad podobný tomuto.
<script>
function soucet(a) {
return function(b) {
return a + b;
}
}
var prictiPetKCislu = soucet(5);
console.log(prictiPetKCislu(10)); // Vrátí 15
var pristiOsmKCislu = soucet(8);
console.log(prictiPetKCislu(3)); // Vrátí 11
</script>
Vytvořil jsem funkci soucet, která přijímá jeden parametr. Uvnitř této funkce v lokálním scope je dostupný tento parametr a.
Funkce nedělá nic jiného, než že vrací anonymní fci, která také přijímá jeden parametr.
Uvnitř anonymní fce je dostupný parametr b, který je v lokálním scope, a parametr a, který fce zdědila z globálního scope.
Je jedno, že jsme funkci soucet zavolali dříve než fci, kterou nám soucet vrátil. Vrácená anonymní fce si svá scope pamatuje celý život aplikace.
Když tedy v prvním případě použití zavolám fci soucet() s parametrem 5, uloží se mi do proměnné prictiPetKCislu anonymní fce, tedy:
prictiPetKCislu = function(b) {
return a + b;
};
K tomu si tato fce pamatuje její globální scope, tedy ten scope ve kterém byla vytvořena. Tím pádem si bude celý zbytek aplikace pamatovat, že existuje nějaká proměnná a a že její hodnota je 5. Může tedy vrátit součet proměnné a a svým parametrem b.
Konečně vysvětlení scriptu
Doufám, že jste již problematiku scope pochopili, tak pro vás již nebude problém pochopit hlavní script.
Na začátku sciptu deklaruju 3 globální proměnné. Hodnotu přiřazji jen první proměnné. Hodnota ostatních zůstává undefined.
Poté tam mám 3 anonymní fce. První vytváří jen lokální proměnnou, takže dál ve scriptu nebude vůbec dostupná a dotaz na tuto proměnnou vyhodí error.
Druhá anonymní fce v pořádku přistoupí ke globální proměnné a přiřadí ji hodnotu.
Třetí fce by udělala to samé, jenže ji pouze vytvářím, ale nevolám. Na konci chybí závorky () naznačující volání. Hodnota této proměnné tedy zůstane undefined.
Pak vytvářím anonymní fci na zapouzdření zbytku kódu. Tato fce přijímá jeden parametr.
Uvnitř je deklarována lokální proměnná a je jí také přiřazena hodnota.
Dále vytvářím fci a ukládám si ji do proměnné. Tato fce přijímá 2 parametry.
Na začátku fce dělám nějakou magii s prvniGlobalniPromennou. Musím to udělat pro vaše zmatení. Kdybych to neudělal, tak později aplikace vyhodí error, protože do výpisu chci přiřadit tuto proměnnou, ale není deklarovaná. Proto ji deklaruji zde.
Pod manévrem na zmatení je ověření callbacku. První testuji, jestli je vůbec callback nastaven. Pokud není, tak vyhodím vyjímku.
To samé hned pod tím. Testuji, jestli je callback function.
Tyto vyhozené vyjímky je možné zachytit try-catch blokem, protože je vyjímka vyhozena v době volání funkce.
Pod ověřením mám setTimeout(), abych nasymuloval nějakou tu asynchronní akci.
Uvnitř setTimeout() první ověřuji parametr. Parametrem vlastně říkám co se má stát, je to kvůli simulaci.
První podmínka vyhodí vyjímku, kterou však nepůjde zachytit, protože script už je dávno za voláním této funkce, takže už je dávno mimo try-catch blokem. Vyjímka tedy nebude zachycena a script skončí chybou a dále nepokračuje.
Druhá podmínka také hodí chybu, ale už stylem Node.js. Jednoduše ji předá do callbacku jako poslední parametr.
No a nakunec tu máme náš výpis, jehož výsledek jste měli uhodnout.
Pokud je parametr string, tak vracím:
(globalniPromenna + " " + param + ": " + prvniGlobalniPromenna + druhaGlobalniPromenna + tretiGlobalniPromenna + lokalniPromenna + " | " + parametr).toUpperCase()
globalniPromenna je normálně dostupná a obsahuje global
param je pro volanou fci z globálního scope, je to parametr předaný anonymní zapoudřující fci. Je také dustupný a obsahuje pozdravy.
prvniGlobaniPromenna obsahuje prázdný řetězec. Byla původně deklarována uplně nahoře, ale v lokálním scope. Já jsem ji předefinoval na prázdný řetězec, jinak by zde vyletěla chyba a script by skončil.
druháGlobalniPromenna obsahuje , Nazdar.
tretiGlobalniPromenna je undefined.
localniPromenna obsahuje , Čau.
a parametr se různí podle volání.
Tohle všechno spojím a převedu na velké znaky a máme výsledek.
Doufám že to chápete. Pokud ne, ptejte se.
Instalace Node.js
Instalace Node.js je poměrně jednoduchá.
Jděte na adresu https://nodejs.org/en/download/stable/ a stáhněte si to co máte.
Instalátory obsahují samotné Node.js a npm (package manager), který si rozhodně také nainstalujte.
Myslím že instalaci nemusím nijak složitě vysvětlovat. Pokud by se vyskytly nějaké neočekávané problémy, tak vám jistě strejda google rád poradí.
První Node.js script
Tak a jdeme "noudit".
Kdekoliv na disku si vytvořte soubor, například prvni-node-script.js
Do toho souboru můžete již psát jakýkoliv JavaScript.
Já jsem pro vás napsal základní scriptík na otestování:
var a = 5;
var b = 6;
console.log("a = ", a);
console.log("b = ", b);
console.log("a + b = ", a + b);
Myslím že script nemusím složitě popisovat.
Vytvořil jsem 2 proměnné a vypsal jsem jejich součet.
Můžete si zkusit hrát a trochu si to osahat.
Ale s využitím základního JavaScriptu toho moc neuděláte. Obzvlášť když zde není žádné window, document a celá DOM struktura.
Každopádně si můžete hrát s třídama a vytvořit si něco. Třeba nějakou hru s rytířem a drakem.
HTTP server
Zde se dostaneme k praktickému využití Node.js a už se konečně seznámíme i s nějakými věcmi, které Node.js k JavaScriptu přidává.
První věc co musím vysvětlit je fce require(). Dělá přesně to co si asi myslíte. Načítá jiné soubory. Ale nedělá to asi tak jak si myslíte.
Fce require opravdu načítá soubory, ale nevrací její obsah a už vůbec ho nevloží do místa volání jako require v PHP. Funkce require zavolá daný soubor a samostatně jej spustí. Tím samostatně myslím opravdu samostatně, protože se v daném souboru nelze dostat k proměnným ani jiným věcem ze souboru, který jej volá. -- Lze to přes globální objekt global, na který můžete přidávat vlastnosti, ale o tom se moc nemluví. --
Na co tedy require je, když z něj nic nedostanu?
Dostanete. Vše co chcete ze souboru (v Node.js jsou tyto requirované soubory spíše moduly) pustit ven, musíte nastavit do objektu module.exports.
Pomocí require tedy načítáme moduly. Pokud načítáme základní moduly z Node.js, udáváme pouze jejich název, bez cesty, bez přípony souboru. Pokud chceme načíst naše vlastní moduly, musíme to udělat i s cestou a příponou souboru.
Takže.. Abychom mohli vytvořit nějaký http server, budeme potřebovat modul http. Můžete si k němu dohledat informace v API, které je asi největším zdrojem informací.
Podle API, http má metodu createServer, která pžijímá jeden parametr. Parametrem je funkce, která je zaregistrována jako requestListener -> tzn. když dojde na server request, zavolá se váše callback funkce.
Váš callback dostane 2 parametry, request a response, díky kterým získáte informace o příchozím dotazu a dostanete možnost a něj i odpovědět.
Rovnou ukážu základní příklad ze stránek Node.js
const http = require('http');
const hostname = '127.0.0.1';
const port = 80;
http.createServer(function(req, res) {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.write("A jak jinak začít než se známou klasikou.\n");
res.end('Hello World\n');
}).listen(port, hostname, function() {
console.log("Server running at http://", hostname, ":", port);
});
Ve scriptu tedy vytváříme http server. Serveru dáváme callback, ve kterém zpracujeme každé příchozí spojení.
Na serveru poté zavoláme metodu listen() a předáme jí IP a port, na kterém má server běžet.
Nyní si můžete v prohlížeči normálně otevřít http://127.0.0.1 a uvidíte vaše Hello World!
Nastavujeme content-type odpovědi na plain text, takže budou špatně vykresleny diakritické znaky.
Trochu si to upravíme a vrátíme už nějaké to HTML.
const http = require('http');
const hostname = '127.0.0.1';
const port = 80;
http.createServer(function(req, res) {
// Zapíšeme čas startu
console.time("request-time");
res.writeHead(200, { 'Content-Type': 'text/html' });
res.write("<!DOCTYPE html>" +
"<html>" +
"<head>" +
"<meta charset='UTF-8'>" +
"<title>Hello World page - special HTML edition</title>" +
"<style>" +
"body, html {margin:0;padding:0;} body { background: #222; color: #eee; padding: 10px;}" +
"</style>" +
"</head>" +
"<body>" +
"<h1>Hello World</h1>" +
"<p>A co ta naše speciální diakritika?</p>" +
"</body>" +
"</html>"
);
res.end(); // Odešleme odpověď
// Vypíšeme si dobu zpracování dotazu
console.timeEnd("request-time");
}).listen(port, hostname, function() {
console.log("Server running at http://", hostname, ":", port);
});
Zde už vracíme plnohodnoutnou HTML stránku, plus jsem přidal výpis do konzole s dobou provádění dotazu.
To je asi v tomto dílu vše. Pokud máte nějaké dotazy či připomínky, klidně piště.
Budu rád, když vám to bude všem fungovat, zalíbí se vám to a u Node.js zůstanete.
Kdy bude další díl těžko říct. Možná ho napíšu ještě dnes.
V dalším díle bych bych už vytvořil nějaký vlastní modul. Nějak bych rozšířil tento základ.
Až tak ve třetím díle bych se pustil třeba do využití Node.js jako pozadí pro AJAX.
Vytvořil bych třeba AngularJS clienta a všechna data by tahal z Node.js serveru.
No a samozřejmě jak jsem měl tento díl skoro hotový, tak jsem zmáčkl nějakou kravinu a přepsala se mi záložka. Když jsem dal z5, tak se objevil automaticky uložený obsah 20 minut z5. Teď už fakt nemám náladu to dopisovat, takže doplním zítra.
EDIT: Doplnil jsem zatím část s opakováním.
EDIT: Doplněno