České vysoké učení technické v Praze Fakulta informačních technologií Katedra softwarového inženýrství
Diplomová práce
SEO analýza webových stránek Bc. Matěj Šerák
Vedoucí práce: Ing. Jan Kopecký, Ph.D
7. května 2013
Poděkování Děkuji svým rodičům a své přítelkyni, že mě podporovali a měli se mnou trpělivost. Rovněž děkuji Ing. Janu Kopeckému, Ph.D. za jeho ochotu a veškerý čas, který mi věnoval.
Prohlášení Prohlašuji, že jsem předloženou práci vypracoval samostatně a že jsem uvedl veškeré použité informační zdroje v souladu s Metodickým pokynem o etické přípravě vysokoškolských závěrečných prací. Beru na vědomí, že se na moji práci vztahují práva a povinnosti vyplývající ze zákona č. 121/2000 Sb., autorského zákona, ve znění pozdějších předpisů, zejména skutečnost, že České vysoké učení technické v Praze má právo na uzavření licenční smlouvy o užití této práce jako školního díla podle § 60 odst. 1 autorského zákona.
V Praze dne 7. května 2013
.....................
České vysoké učení technické v Praze Fakulta informačních technologií c 2013 Matěj Šerák. Všechna práva vyhrazena.
Tato práce vznikla jako školní dílo na Českém vysokém učení technickém v Praze, Fakultě informačních technologií. Práce je chráněna právními předpisy a mezinárodními úmluvami o právu autorském a právech souvisejících s právem autorským. K jejímu užití, s výjimkou bezúplatných zákonných licencí, je nezbytný souhlas autora.
Odkaz na tuto práci Šerák, Matěj. SEO analýza webových stránek. Diplomová práce. Praha: České vysoké učení technické v Praze, Fakulta informačních technologií, 2013.
Abstract This research project tracks the process by which an application for website analysis was designed. It deals with the design and implementation and also introduces the technologies used to build this application, namely: Node.js, AngularJS and NoSQL. The project also includes background research of some existing tools. Keywords SEO, Node.js, JavaScript, AngularJS, NoSQL, MongoDB
Abstrakt Práce popisuje postup tvorby aplikace pro analýzu webové stránky. Zabývá se nejen návrhem a implementací, ale také podrobně představuje technologie, na kterých je aplikace postavena: Node.js, AngularJS či NoSQL. Součastí práce je také rešerše některých již existujících nástrojů. Klíčová slova SEO, Node.js, JavaScript, AngularJS, NoSQL, MongoDB
ix
Obsah Úvod
1
1 Metodika SEO 1.1 On-page a off-page faktory . . . . . . . . . . . . . . . . . . . . . 1.2 Zakázané praktiky . . . . . . . . . . . . . . . . . . . . . . . . .
3 3 7
2 Rešerše 2.1 Google PageSpeed Insights 2.2 Google Webmaster Tools . . 2.3 Majestic SEO . . . . . . . . 2.4 SEOmoz . . . . . . . . . . . 2.5 Collabim . . . . . . . . . . . 2.6 SEO Servis . . . . . . . . . 3 Technologické řešení 3.1 REST . . . . . . . 3.2 Cloud computing . 3.3 HTML5 . . . . . . 3.4 CSS3 . . . . . . . . 3.5 JavaScript . . . . . 3.6 Node.js . . . . . . 3.7 Databáze . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . .
. . . . . . .
. . . . . .
. . . . . . .
. . . . . .
. . . . . . .
. . . . . .
. . . . . . .
. . . . . .
. . . . . . .
. . . . . .
. . . . . . .
. . . . . .
. . . . . . .
. . . . . .
. . . . . . .
. . . . . .
. . . . . . .
. . . . . .
. . . . . . .
. . . . . .
. . . . . . .
. . . . . .
. . . . . . .
. . . . . .
. . . . . . .
. . . . . .
. . . . . . .
. . . . . .
. . . . . . .
. . . . . .
. . . . . . .
. . . . . .
. . . . . . .
. . . . . .
. . . . . . .
. . . . . .
. . . . . . .
. . . . . .
9 9 9 10 11 12 13
. . . . . . .
15 15 19 22 26 27 36 39
4 Analýza a návrh 43 4.1 Analýza požadavků . . . . . . . . . . . . . . . . . . . . . . . . . 43 4.2 Návrh uživatelského rozhraní . . . . . . . . . . . . . . . . . . . 47 4.3 Návrh architektury systému . . . . . . . . . . . . . . . . . . . . 48 5 Implementace 55 5.1 Konfigurace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55 xi
xii
OBSAH 5.2 5.3 5.4
Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Controller . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . View . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
56 58 64
6 Testování 67 6.1 Jednotkové testování . . . . . . . . . . . . . . . . . . . . . . . . 67 6.2 Integrační testování . . . . . . . . . . . . . . . . . . . . . . . . . 69 6.3 End-to-end testování . . . . . . . . . . . . . . . . . . . . . . . . 70 Závěr
73
Literatura
75
A Seznam použitých zkratek
81
B Seznam HTTP stavových kódů
83
C Dokumentace RESTful API
89
D Pokyny k instalaci
93
E Screenshoty
95
F Obsah přiloženého CD
103
Seznam obrázků 2.1
Flow metriky webů www.cvut.cz a www.seznam.cz . . . . . . . . .
11
3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11
Stateful server . . . . . . . . . . . . . . . . . . . . . . . . . . Stateless server . . . . . . . . . . . . . . . . . . . . . . . . . . Vývoj dodávky ICT služeb . . . . . . . . . . . . . . . . . . . Rozdělení cloud computingu . . . . . . . . . . . . . . . . . . . Chování prohlížeče Safari v závislosti na typu vstupního pole Struktura blogu podle HTML4 a HTML5 . . . . . . . . . . . Zkušenosti Bena Nadela s AngularJS . . . . . . . . . . . . . . One-Way Data-Binding . . . . . . . . . . . . . . . . . . . . . Two-Way Data-Binding . . . . . . . . . . . . . . . . . . . . . Rozdělení databázových systémů podle CAP teorému . . . . Skladba identifikátoru záznamu . . . . . . . . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
17 17 20 21 24 26 31 32 32 41 42
4.1 4.2 4.3 4.4 4.5
Prototyp uživatelského rozhranní . . Diagram nasazení . . . . . . . . . . . Diagram aktivit – zobrazení testu . . Diagram aktivit – vytvoření testu . . Sekvenční diagram – vytvoření testu
. . . . .
. . . . .
. . . . .
47 49 51 52 53
6.1 6.2
Scenario Test Runner . . . . . . . . . . . . . . . . . . . . . . . . . Scenario Test Runner . . . . . . . . . . . . . . . . . . . . . . . . .
71 72
E.1 E.2 E.3 E.4 E.5 E.6 E.7 E.8
Nový test . . . . . . . . . . Nový test – spuštění . . . . Historie provedených testů . Detail testu – přehled . . . Detail testu – obsah . . . . Detail testu – odkazy . . . Detail testu – rychlost . . . Editace testu . . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
xiii
. . . . . . . .
. . . . .
. . . . . . . .
. . . . .
. . . . . . . .
. . . . .
. . . . . . . .
. . . . .
. . . . . . . .
. . . . .
. . . . . . . .
. . . . .
. . . . . . . .
. . . . .
. . . . . . . .
. . . . .
. . . . . . . .
. . . . .
. . . . . . . .
. . . . .
. . . . . . . .
. . . . .
. . . . . . . .
. . . . .
. . . . . . . .
. . . . .
. . . . . . . .
. . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. 95 . 96 . 97 . 98 . 99 . 100 . 101 . 102
Seznam tabulek 2.1
Určení hodnoty ACRanku . . . . . . . . . . . . . . . . . . . . . . .
11
3.1 3.2 3.3 3.4
HTML5 – podpora formulářových atributů v prohlížečích HTML5 – podpora typů vstupních polí v prohlížečích . . HTML5 – podpora Web Applications v prohlížečích . . . Populární NoSQL databáze . . . . . . . . . . . . . . . . .
. . . .
24 25 27 40
4.1 4.2
Popis RESTful webové služby . . . . . . . . . . . . . . . . . . . . . Kontroly prováděné v rámci RESTful webové služby . . . . . . . .
50 50
5.1 5.2 5.3
Popis RESTful webové služby . . . . . . . . . . . . . . . . . . . . . Popis API pro AngularJS . . . . . . . . . . . . . . . . . . . . . . . Zdroje pro získávání informací o stránce . . . . . . . . . . . . . . .
59 59 60
xv
. . . .
. . . .
. . . .
. . . .
Seznam výpisů kódu 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11
HATEOAS . . . . . . . . Deklarace třídy . . . . . . Změna instance . . . . . . Closure . . . . . . . . . . Hoisting 1 . . . . . . . . . Hoisting 2 . . . . . . . . . Zapouzdření jQuery kódu Definice controlleru . . . . Definice služby . . . . . . Aplikace direktivy . . . . Anotace $inject . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
19 28 29 29 30 30 30 34 34 34 34
5.1 5.2 5.3 5.4 5.5 5.6 5.7 5.8 5.9
Schéma pro kolekci Test . . . . . . . . . . . Schéma Test – statické metody . . . . . . . Schéma User – instanční a statické metody Použití modulu Async . . . . . . . . . . . . Historie testů . . . . . . . . . . . . . . . . . Smazání účtu uživatele v AngularJS . . . . Služba $routeProvider . . . . . . . . . . . . Služba $locationProvider . . . . . . . . . . . Rozšíření $resource pro komunikaci s API .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
57 57 58 59 62 63 65 65 65
6.1 6.2 6.3 6.4 6.5
Nastavení frameworku Mocha v souboru mocha.opts . . . Příklady některých možných assertů s modulem Should.js Jednotkový test s použitím modulu Should.js a Mocco . . Otestování metody PUT integračním testem . . . . . . . . Spuštění jednotkových a integračních testů pod Windows
. . . . .
. . . . .
. . . . .
68 68 68 69 70
xvii
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
Úvod Dynamický rozvoj internetu a informačních technologií přinesl řadu nových přístupů v marketingu. Internet se stal velmi silným a samostatným marketingovým nástrojem, a přesunul se tak z pozice nástroje podpůrného. Jeho dominance mezi ostatními marketingovými nástroji spočívá zejména ve vysoké míře interaktivity uživatelů, kteří jsou přímo zapojeni do marketingového procesu. Mezi nosné pilíře internetového marketingu v současné době patří mimo jiné i SEO (Search Engine Optimization), optimalizace pro vyhledávače, kterou se budu zabývat v této práci. Na trhu existuje velké množství automatických analyzátorů webových stránek. Některé z těchto analyzátorů, ačkoliv nemají v názvu přívlastek SEO, přitom v jistém smyslu se SEO souvisejí. Kupříkladu i tolik zpochybňovaná validita se nepřímo dotýká SEO, protože nevalidní stránky může v některých případech prohlížeč delší dobu renderovat (kvůli neukončeným elementům, zanořeným tabulkám apod.). Tím se zvyšuje míra opuštění (Bounce rate), což má z pohledu SEO dlouhodobě neblahý dopad. Proto i z takovýchto nástrojů budu čerpat inspiraci a v diplomové práci je využiji. Tato práce si dává za cíl vytvořit nástroj, který zanalyzuje webovou stránku v co nejširším rozsahu. Velký důraz byl kladen na výběr technologií, které proto figurují přímo v zadání. Vzhledem k tomu, že tyto technologie využiji vůbec poprvé, je právě jejich osvojení pro mne tou největší motivací.
1
Kapitola
Metodika SEO SEO je komplexní soubor aktivit spojených s tvorbou, provozem a propagací internetové stránky, který zajistí dobré umístění stránek ve výsledcích vyhledávání v SERP1 na relevantní klíčové fráze. SEO nemusí zajistit vždy první místo ve vyhledávání na klíčová slova. Stačí, když cíloví zákazníci stránky přes vyhledávač najdou. Optimalizace pro vyhledávače je nikdy nekončící proces vyžadující opakované analýzy, vyhodnocování jejich výsledků a následné implementace změn odstraňující slabá místa. Stejně jako je důležité provádět vstupní analýzy, je třeba provést i výstupní analýzy (zdrojů návštěv, prostupnosti stránek apod.), které pomohou právě s vyhledáním slabých míst a nežádoucích efektů. V souvislosti se SEO se občas mluví i o SEM (Search Engine Marketing), tj. marketingu ve vyhledávání. SEM lze při velkém zjednodušení přirovnat k „placenému SEO“. Vyhledávací marketing pod sebou sdružuje nákupy placených zvýrazněných pozic nad výsledky vyhledávání a na dalších relevantních místech. SEM zastřešuje také nákupy PPC reklam, registrace do placených katalogů nebo zvýhodnění základních zápisů. Na rozdíl od SEO je efekt SEM okamžitý. [56]
1.1
On-page a off-page faktory
Faktory ovlivňující umístění ve výsledcích vyhledávání se dělí na on-page (faktory na stránce) a off-page (faktory mimo samotný web). Důležitost jednotlivých faktorů pro vyhledávač Google lze nalézt na webu seomoz.org. Tento vážený seznam faktorů sestavila skupina více než 130 odborníků, kteří se metodikou SEO dlouhodobě zabývají. V českém prostředí vznikl podobný seznam na webu seofaktory.cz. Oproti zahraniční předloze je zde zohledněn i český vyhledávač Seznam. 1
SERP – Search Engine Results Page, strana výsledků vyhledávání
3
1
1. Metodika SEO Souhrnně lze říci, že jak on-page, tak i off-page faktory mají velký vliv na pozici stránky v SERP: • podle on-page faktorů vyhledávač rozhodne, zda danou stránku do SERP vůbec zahrne, • podle off-page faktorů vyhledávač rozhodne, na jaké pozici danou stránku v SERP zobrazí.
1.1.1
On-page SEO
On-page SEO patří v dnešní době ke standardům většiny dodavatelů. Nejvýznamnější on-page faktory se týkají sémantiky kódu, obsahu a provázanosti stránek. Sémantika zdrojového kódu Dodržování sémantiky zdrojového kódu znamená, že obsah stránek bude označkován v souladu s významem jeho jednotlivých částí. Vyplatí se využít mikroformáty, mikrodata (Googlem jsou upřednostňovány) či standard RDFa. Vyhledávače pak mohou zobrazit danou stránku v SERP odlišně, díky čemuž se zvyšuje pravděpodobnost, že zrovna na tuto stránku uživatel ze SERP přejde. Relevance obsahu ke klíčovým slovům a jedinečnost obsahu Obsahový marketing je v současné době velmi populární. I největší sociální sítě pochopily, že budoucnost je v obsahu. Proto neustále rozšiřují svoje služby o nové možnosti jeho sdílení či hodnocení. Obsahový marketing ale není honba za objemem, nýbrž za kvalitou a relevancí. Proto i když existují teorie, že z pohledu SEO by hustota klíčových slov měla být někde kolem 2–3 %, je většinou důležitější stylistická kvalita, informační hodnota a jazyková pestrost textu. Ideální text by tedy měl obsahovat co nejvíce různých klíčových slov s podobným významem, zároveň by však měl být srozumitelný, čtivý, přesvědčivý a přirozený. [41] Přehlednost a provázanost jednotlivých stránek Vhodně navržená struktura webu může zvýšit jeho souhrnný rank (součet ranků všech stránek). Zároveň může dojít k pozitivnímu přesunu ranku z méně důležitých stránek na stránky důležitější. Je logické, že pokud se lze na některou stránku dostat pouze provedením 5 kliknutí, není tato stránka příliš důležitá. Pro vyhledávač tak bude mít větší váhu stránka, na kterou vede odkaz přímo z úvodní stránky. [6] Např. pokud se na některou stránku dostane uživatel z úvodní stránky až po 5. kliknutí, znamená to logicky, že tato stránka není tak důležitá. 4
1.1. On-page a off-page faktory
1.1.2
Off-page SEO
Realizace off-page SEO vyžaduje na začátku provést několik vstupních analýz, zejména analýzy relevantních klíčových slov a frází a analýzy konkurence v SERP. V souvislosti s off-page optimalizací se doporučuje registrovat web do katalogů, pořídit dobře zacílenou reklamu a snažit se o zvyšování obecného povědomí o webové stránce na internetu. Nejdůležitějším off-page faktorem je ale linkbuilding (budování zpětných odkazů). Podle počtu a kvality zpětných odkazů vypočítávají vyhledávače rank stránky – Google jej označuje jako PageRank, Seznam má pro změnu S-rank. [56] PageRank PageRank popsali zakladatelé Googlu Larry Page a Sergey Brin v roce 1996 ve své výzkumné práci The Anatomy of a Large-Scale Hypertextual Web Search Engine. Pro výpočet PageRanku jedné stránky je třeba znát PageRank všech stránek, které na ni odkazují. Proto se výsledný PageRank počítá v iteracích a jeho hodnota po několika iteracích konverguje k reálnému číslu. V matematickém pojetí dosahuje PageRank hodnot od 0 do 1, navenek je prezentován jako hodnota od 0 do 10 (Toolbar PageRank). S-rank S-rank je veličina, která by měla vyjadřovat důležitost stránky na českém webu. Přesný vzorec není veřejný, Seznam pouze prozrazuje, že se počítá váženou nelineární kombinací různých veličin, v nichž výrazně převažují off-page faktory. Výpočet se podobá známému algoritmu Hubs & Authorities 2 , ale je upraven tak, aby dával smysl i pro netematické množiny stránek. Alexa Rank Alexa Rank je veličina, která hodnotí doménu (tedy ne každou URL) na základě sledování návštěvnosti uživateli, kteří mají nainstalovaný Alexa Toolbar. Jedná se o metriku vyvinutou společností Alexa, kterou v roce 1999 koupil za 250 mil. dolarů Amazon. [54] Alexa Rank nabývá hodnot od 10 miliónů do jedné – čím méně, tím lepší postavení. Nad reprezentativností Alexa Ranku se velmi diskutuje, především z důvodu geografického rozložení uživatelů s instalovanou lištou. Může k němu být přihlédnuto např. při orientačním určení hodnoty webu.
1.1.3
Ostatní faktory
Kromě on-page a off-page faktorů existují i faktory, které nemůžeme přímo ovlivnit a přesto mohou mít vliv na výslednou podobu SERP. 2
http://www.cs.cornell.edu/home/kleinber
5
1. Metodika SEO Trend v získávání nových odkazů Pokud stránka získává v dlouhodobém horizontu průměrně 5 zpětných odkazů denně a začne najednou získávat 10 zpětných odkazů, může to být pro vyhledávač pozitivním znamením. Pokud naopak dojde k poklesu v získávání nových zpětných odkazů, je to pro vyhledávač znamení, že se stránka stává méně relevantní. Nejen celkové množství zpětných odkazů, ale i trend v jejich získávání může hrát v algoritmu sestavování SERP jistou úlohu. Vyhledávač ovšem musí odhalit, zda se za dramatickým nárůstem neskrývá např. nákup či výměna odkazů. Koncept získávání informací s ohledem na časový horizont popisuje Google v patentu US 20050071741 A1 – Information retrieval based on historical data 3 . [6] Tento patent zmiňuje nejen důležitost dynamiky získávání zpětných odkazů, ale i důležitost aktuálnosti dokumentu a kvality domény (její stáří; doba, za kterou expiruje; reputace serveru, na kterém je hostována). Data z používání SERP Pokud uživatel přejde na určitou stránku ze SERP, následně se vrátí zpět a vybere si jinou stránku, může to být vnímáno vyhledávačem jako negativní signál. Stejně tak, pokud uživatel přejde na poslední stránku v SERP, je to vnímáno pro tuto stránku pozitivně a naopak negativně pro všechny stránky, které se nacházejí v SERP výše. Není známo, jak moc vyhledávače tuto zpětnou vazbu od uživatelů sledují, ačkoli ji Google také popisuje ve výše zmíněném patentu. Přinejmenším hraje zpětná vazba velkou úlohy při personalizaci výsledků vyhledávání. [6] Uživatelská data Na základě různých uživatelských dat může vyhledávač značně přizpůsobit SERP. Např. prostřednictvím geolokace zobrazí uživateli na dotaz „Hotel Hilton“ nejdříve ty hotely, které jsou nejblíže, a pak až všechny ostatní. Vyhledávače také využívají historii vyhledávání. Pokud si uživatel vybere na určitý dotaz výsledek, který byl v SERP na 5. pozici, dost pravděpodobně bude příště tento výsledek na stejný dotaz v SERP výše. Z hlediska historie mohou vyhledávače sledovat i kontext vyhledávání. Pokud uživatel vyhledával v minulosti „php“ a nyní vyhledává „ruby“, vyhledávač ví, že ho zajímá programovací jazyk, nikoliv drahokam. Při optimalizaci webových stránek je také důležité prozkoumat, jaké související termíny vyhledávač uživateli našeptává. Kdyby vyhledávače uživatelům nenašeptávaly, velká část uživatelů by vyhledávala termín trochu odlišný. Našeptávání má proto z pohledu SEO výrazný vliv. [9] 3
6
http://www.google.com/patents/US20050071741
1.2. Zakázané praktiky
1.2
Zakázané praktiky
Jakákoliv úprava webové stránky, která se snaží obelstít vyhledávač, a nalákat tak větší množství návštěvníků, je označována jako black hat SEO. Mezi praktiky black hat SEO patří zejména: • nadměrná výměna či prodej odkazů (tvorba linkové farmy), • „tapetování“ klíčovými slovy, • manipulace s obsahem – duplicitnost, „vykrádání“, skrývání, automatické generování, • využívání doorway stránek či cloakingu. Doorway stránky mají obsah „přeoptimalizováný“ pro indexovací roboty. Protože však takto optimalizovaná stránka nedokáže plnit svůj marketingový úkol, využívá přesměrování návštěvníka (většinou s pomocí JavaScriptu) na cílovou stránku. Cloaking je obdobnou technikou. Spočívá v podstrčení jiného obsahu indexovacímu robotovi a návštěvníkovi, ale na rozdíl od doorway stránek se přesměrování neprovádí JavaScriptem. Technicky na této metodě není nic těžkého, např. se v mod_rewrite skrze RewriteCond dává do podmínky buďto IP adresa, nebo User-Agent, případně se obě podmínky spojí přes OR. Někdy může vyhledávač dostat jiný obsah než návštěvník a přesto se nemusí jednat o nekalou praktiku. Vyhledávače využívají základní princip cloakingu k odkrývání tzv. neviditelného webu, tj. obsahu skrytého v různých databázích a na stránkách jen pro platící či registrované uživatele. Google má např. dohody o cloakingu s několika americkými zpravodajskými servery. Tyto servery tak sice zobrazují jiná data vyhledávači a jiná uživateli, ale nepoužívají cloaking v jeho obvyklém smyslu. [40]
7
Kapitola
Rešerše 2.1
Google PageSpeed Insights
PageSpeed Insights4 je nástroj, který změří rychlost načítání webu, odhalí příčiny pomalého načítání a formuluje doporučení, jak web optimalizovat. Výsledkem testu je PageSpeed Score v hodnotě 0 až 100, které dá představu i laikům, jak dobře je web optimalizován. Nalezené problémy jsou rozděleny podle stupňů priority do 3 kategorií: vysoká, střední a nízká. Vývojář dostane také pár „experimentálních“ tipů. Z diagramu Critical Path Explorer pak lze vyčíst, jakým podílem se které části stránky podílí na celkové době načítání. Analýzu webové stránky lze provést na webu PageSpeed Insights, případně jsou k dispozici rozšíření do prohlížečů Chrome a Firefox. Poslední možností využití této služby je implementace poskytovaného API. Zdarma je možné takto denně otestovat 2 500 stránek. Google je v oblasti zrychlování webu průkopníkem. V jeho portfoliu tak nalezneme např. nedávno spuštěnou službu Google PageSpeed Service. Jedná se o proxy server, který přepisuje obsah poskytovaný originálním serverem a přitom provádí velké množství optimalizací. Google také vytvořil mod_pagespeed, open-source modul pro Apache HTTP Server, který se skládá ze sady filtrů provádějících automaticky optimalizaci webové stránky a připojených zdrojů (obrázků, JavaScriptu, CSS).
2.2
Google Webmaster Tools
Google Webmaster Tools5 je nástroj od společnosti Google určený webmasterům. Umožňuje správci stránek kontrolovat nejrůznější statistiky týkající se indexace a viditelnosti stránek. Reporty obsahují informace o: 4 5
http://developers.google.com/speed https://www.google.com/webmasters/tools
9
2
2. Rešerše • existenci a validitě souboru sitemap.* (Google se řídí protokolem Sitemap 0.96 ), • existenci a obsahu souboru robots.txt, • chybách v procházení stránek, • klíčových slovech v obsahu stránky aj. Zejména poslední bod je zajímavý – Google předpokládá, že nejčastěji zastoupená slova v textu stránky jsou pilířem obsahového marketingu. Pokud se mezi nejdůležitějšími slovy nachází fráze jako „související produkty“, „kontaktujte nás“ nebo „klikněte zde“, bude se SEO v tomto směru nejspíš něco v nepořádku.
2.3
Majestic SEO
Majestic SEO7 je služba, která získává informace o zpětných odkazech. Obsahuje databázi čítající více než 200 miliard webových stránek (unikátních URL) a k nim vážících se zpětných odkazů. [18] Indexovací robot Majestic SEO prochází stránky podobně jako např. Googlebot, do databáze si ale ukládá pouze informace o zpětných odkazech, nikoliv kompletní obsah stránek. Základní přehledy jsou zdarma, plnohodnotný tarif začíná na 40 dolarech měsíčně a např. tarif umožňující využívání API stojí 300 dolarů měsíčně. Analýzou libovolné stránky prostřednictvím Majestic SEO obdržíme charakteristiku odkazového profilu zahrnující mimo jiné: • počet externích a interních odkazů, • přehled některých vlastností nalezených odkazů (např. follow), • nalezené URL adresy v textu stránek, které ale nejsou aktivními odkazy, • vývoj odkazů v historickém kontextu apod. Majestic SEO zkoumá také důležitost jednotlivých odkazů. Dříve pro tyto účely používal ACRank, vlastní rank, který nabýval hodnoty 0–15 v závislosti na počtu domén, které odkazovaly na danou stránku (přepočet viz Tabulka 2.1). Od března 2012 používá metriky Citation Flow a Trust Flow, které mohou nabývat hodnot od 0 do 100. [17] Citation Flow je obdoba dřívějšího ACRanku. Tato metrika říká, jaký je vliv dané stránky. Vlivnost hodnotí podle počtu a váhy zpětných odkazů. Umístění odkazu na stránce (postranní sloupec, patička) není ve výpočtu zohledněno. 6 7
10
http://www.sitemaps.org/protocol.html http://www.majesticseo.com
2.4. SEOmoz Tabulka 2.1: Určení hodnoty ACRanku ACRank Počet odkaz. domén ACRank Počet odkaz. domén ACRank Počet odkaz. domén
1 1 6 72 11 17 496
2 2 7 216 12 52 488
3 4 8 648 13 157 464
4 8 9 1 944 14 472 392
5 24 10 5 832 15 1 417 176
Obrázek 2.1: Flow metriky webu cvut.cz a seznam.cz
Metrika Trust Flow vyjadřuje důvěryhodnost dané stránky. Předpokladem této metriky je, že weby odkazují pouze na důvěryhodné sousedy. Širokému výběru autoritativních webů (weby vzdělávacích institucí, weby státní správy apod.) je důvěryhodnost určena manuálně, ostatním webům pak je předávána odkazem. Odkazy s atributem nofollow nejsou započítávány do hodnocení ani jedné z metrik. [51] Z Obrázku 2.1 je patrné, že weby www.cvut.cz i www.seznam.cz vlastní velké množství kvalitních zpětných odkazů.
2.4
SEOmoz
Společnost SEOmoz8 vznikla v roce 2004 coby konzultační agentura, od roku 2010 se ale soustřeďuje také na vývoj vlastních nástrojů pro automatické vyhodnocení webových stránek. Mezi tyto nástroje patří např.: • Open Site Explorer (OSE)9 – analýza zpětných odkazů, • Rank Tracker – sledování pozice ve vyhledávačích Google, Yahoo a Bing, 8 9
http://www.seomoz.org http://www.opensiteexplorer.org
11
2. Rešerše • On-Page Optimization Tool – optimalizace stránek na klíčová slova, • Crawl Test – kontrola dostupnosti odkazů a viditelnosti pro vyhledávače • a dalších cca 5 obdobných nástrojů. Jako jediný nástroj lze zdarma využít OSE, ovšem pouze s omezenou funkcionalitou. Všechny ostatní nástroje jsou součástí placeného balíčku. Tarify stojí 100, 200 nebo 500 dolarů měsíčně, přičemž nejlevnější tarif je možné využívat první měsíc bezplatně. K dispozici je také API. Plnohodnotné API vyjde na 500 až 10 000 dolarů měsíčně, v závislosti na četnosti využití. Verze zdarma umožňuje volat API maximálně jednou za 10 vteřin. SEOmoz indexuje 82 miliard webových stránek (unikátních URL). Oproti Majestic SEO je tak jeho databáze (nazývaná Mozscape index) méně než poloviční. Na svém blogu10 uveřejňuje SEOmoz pravidelně statistiky týkající se zaindexovaných stran. Díky tomu si můžeme udělat představu, jak vypadá odkazový profil průměrné internetové stránky: • obsahuje 73 odkazů – 63 externích a 10 interních, • 2 % všech odkazů je označeno atributem nofollow, • 56 % nofollow odkazů představují odkazy interní, • 15 % stránek obsahuje atribut canonical. [37]
2.5
Collabim
Collabim11 je původem český SEO nástroj, který vytvořil v roce 2009 Jiří Koutný. Jedná se o nástroj, který je primárně určen internetovým agenturám, webovým studiím a SEO konzultantům. V České republice jej používají i ty největší agentury zabývající se internetovým poradenstvím (H1.cz s.r.o., Dobrý web s.r.o.). V roce 2011 vyhrál Collabim soutěž API Mashup Contest. Collabim pomáhá zejména s měřením pozic ve vyhledávačích na různá klíčová slova, hledáním kvalitních webů pro linkbuilding a při reportování. Dále umí také přikládat faktury, importovat klíčová slova, vytvářet automatické zprávy pro nákup odkazů, sledovat finance aj. Tarif pro analýzu jednoho webu bez pokročilých funkcí je zdarma. Plnohodnotné tarify stojí od 450 do 6 000 Kč měsíčně, v závislosti na počtu spravovaných webů. 10 11
12
http://www.seomoz.org/blog http://www.collabim.cz
2.6. SEO Servis
2.6
SEO Servis
Nástroj SEO Servis12 vznikl v roce 2006, a byl tak v České republice mezi prvními službami tohoto typu. Uživatelé mohou na stránce odesláním 4 formulářů zjistit informace týkající se např. validity, sémantiky, zdrojového kódu, ranků, odkazového portfolia či popularity na sociálních sítích. SEO servis a podobné služby, které nabízejí tzv. „instantní“ SEO, jsou trnem v oku mnoha lidem, kteří se (nejenom) SEO dlouhodobě zabývají: • Michal Kubíček: Pozor na podvodné SEO analyzátory13 • Pavel Ungr: SEO analyzátor 2 – další faul na uživatele od SEO Expertů14 • Jan Tichý: SEOmaty jsou k ničemu15 • Petr Soukup: Nesnáším SEO analyzátory16 • Daniel Dočekal: SEO Analyzátor od SEO Expert s.r.o. je blábol17 Hlavní problém spatřují tito odborníci ve způsobu prezentace výsledků uživatelům. Výsledky jsou sumarizovány do jednoho diskutabilního čísla a uživateli je nabídnuto školení, oprava či jiná placená služba. Veškeré reporty jsou trvale dohledatelné a vzhledem k tomu, že obsahují množství klíčových slov, mohou nakonec v SERP přeskočit i stránku, kterou se daná analýza zabývá. Uživatel nezíská ani zpětný odkaz, neboť všechny odkazy jsou opatřeny atributem nofollow.
12
http://seo-servis.cz http://michalkubicek.cz/pozor-na-podvodne-seo-analyzatory 14 http://blog.bloxxter.cz/seo-analyzator-dalsi-faul-na-uzivatele-od-seo-expertu 15 http://blog.medio.cz/seomaty-jsou-k-nicemu 16 http://www.souki.cz/nesnasim-seo-analyzatory 17 http://www.pooh.cz/pooh/a.asp?a=2017071 13
13
Kapitola
Technologické řešení 3.1
REST
Representational State Transfer (REST) je architektonický styl zaměřený na síťově orientované aplikace s předpokládanou dlouhou životností. [8] Tento pojem poprvé použil ve své disertační práci v roce 2000 Roy Thomas Fielding, jeden z hlavních autorů HTTP specifikace a spoluzakladatel webového serveru Apache. [7] REST tedy není standard, ale přístup k vývoji a poskytování služeb na internetu. „Representational State Transfer is intended to evoke an image of how a welldesigned Web application behaves: a network of web pages (a virtual statemachine), where the user progresses through an application by selecting links (state transitions), resulting in the next page (representing the next state of the application) being transferred to the user and rendered for their use.“ Roy Thomas Fielding [7]
Přístup, který popisuje REST, není v podstatě ničím novým, neboť největší známou implementací systému, který splňuje omezení stylu REST, je World Wide Web (WWW), zkráceně web. Hlavní přínos disertační práce R. T. Fieldinga ovšem spočívá v tom, že správně analyzuje, proč je web tak úspěšný. [42] A výsledkem této analýzy je architektonický styl REST. REST klade důraz zejména na: • škálovatelnost komunikujících komponent, • obecné rozhraní, • nezávislé nasazení komponent, • použití zprostředkovatelů pro snížení latence, zvýšení bezpečnosti a zapouzdření systémů. 15
3
3. Technologické řešení Při pohledu na dnešní web není problém ověřit, že všech těchto cílů web skutečně dosáhl: • web exponenciálně narůstá a přesto funguje velmi dobře, • web umožňuje přístup různým uživatelům různými přístupovými mechanismy, • komunikace typu starý klient – nový server a nový klient – starý server nepředstavuje problém, • zprostředkovatele představují nejrůznější proxy servery. [42]
3.1.1
Omezení
REST dosahuje výše zmiňovaných cílů definováním následujících šesti omezení (4. omezení volitelně). Aplikace, které využívají principu REST, jsou označovány jako RESTful. [53] 1. klient-server (client-server), 2. bezstavovost (stateless), 3. možnost využití vyrovnávací paměti (cacheable), 4. kód na vyžádání (code on demand), 5. vrstvený systém (layered system), 6. jednotné rozhraní (uniform interface). Klient-server Toto omezení říká, že systém dodržuje architektonický styl klient-server. Tento styl je nejčastěji využíván pro síťové aplikace. Komponenta server nabízí definovanou množinu služeb a naslouchá požadavkům na tyto služby. Komponenta klient, která chce využívat službu, odešle na server požadavek. Server pak požadavku buďto vyhoví, nebo jej zamítne, a informuje klienta o výsledcích v odpovědi. Toto omezení úzce souvisí s principem Separation of Concerns (SoC). SoC říká, že v rámci systému by zodpovědnosti jeho jednotlivých částí měly být oddělené. Díky dodržení omezení klient-server není klientská část zatížena správou dat a serverová část nemusí řešit jejich prezentaci. Obojí přispívá k lepší přenositelnosti klienta a větší škálovatelnosti. [7] 16
3.1. REST
Obrázek 3.1: Stateful server [45]
Obrázek 3.2: Stateless server [45]
Bezstavovost Veškerá komunikace mezi klientem a serverem musí být bezstavová. Požadavek od klienta tak musí vždy obsahovat všechny informace nutné k vykonání požadavku a nesmí využívat žádné informace uložené na serveru. Tato podmínka má pozitivní vliv na škálovatelnost a spolehlivost – vzhledem k tomu, že si server neukládá stav jednotlivých aplikací, je zotavení z případné chyby mnohem jednodušší. [7] Možnost využití vyrovnávací paměti Data odesílaná v odpovědi na požadavek jsou označena příznakem cacheable či non-cacheable, díky čemuž klient ví, zda může získaná data v budoucnu opětovně využít. Zapojení vyrovnávací paměti může komunikaci mezi klientem a serverem výrazně omezit. Díky tomu dojde ke zvýšení efektivity, škálovatelnosti a reálného výkonu aplikace. [7] Kód na vyžádání Při některých požadavcích je možné odesílat nejen data, ale i kód, který se pak vykoná na klientovi (např. JavaScript). Tím, že se neposílají data, dochází ke 17
3. Technologické řešení snížení viditelnosti, proto by tato podmínka měla být použita pouze v místech, kde je to výhodné nebo skutečně zapotřebí. [7] Vrstvený systém Vrstvený systém je rozdělen do několika hierarchických vrstev, přičemž každá vrstva může využívat služby nižší vrstvy a naopak je sama využívána vyšší vrstvou. Jakékoliv jiné komunikace mezi vrstvami jsou zakázány. Složitost implementace některé z vrstev je tak snížena pouze na znalosti nižší vrstvy. Toto omezení umožňuje vkládat mezi klienta a server další uzly (prostředníky – proxy servery, cache servery, brány aj.). Umístění prostředníků může být výhodné pro vylepšení propustnosti, prosazování bezpečnostní politiky nebo zjednodušení komponent přesunutím málo používaných funkcí na jednoho z prostředníků. [20] Jednotné rozhraní Jednotné rozhraní je pravděpodobně nejdůležitější podmínkou konceptu REST. Jednotné rozhraní je dosaženo zejména využíváním HTTP protokolu, ale je třeba si uvědomit, že REST není na HTTP protokol pevně vázán. Pro definici jednotného rozhraní R. T. Fielding uvádí tato omezení [7]: • Identifikace zdroje – jednotlivé zdroje jsou jednoznačně identifikovány prostřednictvím URI (Uniform Resource Identifier). Je ovšem rozdíl mezi zdrojem samotným a jeho reprezentací, kterou obdrží klient. Server neodesílá klientovi výpis konkrétního zdroje, nýbrž odesílá data, která jsou ve formátu, jazyce a kódování, které požaduje klient. • Manipulace se zdrojem skrze jeho reprezentaci – klient, který vlastní reprezentaci určitého zdroje včetně připojených metadat, má dostatek informací, aby byl schopen zdroj modifikovat, pokud má k této operaci potřebná oprávnění. • Samovysvětlující zpráva – každá zpráva by měla obsahovat veškeré informace nutné pro její úspěšné zpracování. Je třeba tak definovat standardizované metody a standardizované typy médií. V případě použití HTTP protokolu můžeme jako standardizované metody brát přímo HTTP metody (GET, POST, . . . ) a jako standardizované typy medií MIME Content-Type (text/plain, text/xml, . . . ). • Hypermedia as the engine of application state (HATEOAS) – hypermedia (rozšíření hypertextu) poskytuje speciální informaci o tom, jak měnit stav zdroje. Klient může komunikovat se serverem pouze pomocí hypermedia a nepotřebuje k tomu žádnou další technologickou informaci. V případě webových služeb je HATEOAS přítomen v podobě odkazů 18
3.2. Cloud computing uvnitř (XML/JSON) dokumentů, které představují zdroje. U XML dokumentů se pro odkazy často používá specifikace Atom18 a z ní konkrétně element link. Pojmenování jednotlivých relací uvnitř odkazů je částečně standardizováno19 , takže se používají např. následující (samopopisná) jména: chapter, edit, first, icon, last, next, payment, previous, self, stylesheet apod. [23] Výpis kódu 3.1: HATEOAS [23] 1 2 3 4 5 6 7 8
< product id = " 42 " > < link rel = " self " href = " http: // amazon . com / product /42 " type = " application / xml " / > < link rel = " payment " href = " http: // amazon . com / checkout /42 " type = " application / xml " / > < name > Kindle Touch name > < price > 139 price > product >
3.2
Cloud computing
Velmi diskutovaným tématem a také využívanou technologií a obchodním modelem dnešní doby je cloud computing. První zmínky o tomto konceptu pochází z přelomu století a posledních několik let se stal opravdu používaným, přesto žádná definice cloud computingu neexistuje. Existuje iniciativa nazvaná Open Cloud Manifesto20 (OCM), ale ta je zaměřena na otevřenost cloudu a přenositelnost dat – žádnou definici cloud computingu zde nenajdeme. [39] Luis M. Vaquero se ve svém článku [50] pokouší sloučením různých definic cloud computingu od různých autorů sjednotit pohled na tento termín. Z porovnání definic vyplývá, že cloudy jsou velké skupiny snadno použitelných a dostupných ICT zdrojů (jako hardware, vývojové platformy nebo aplikace). Tyto zdroje mohou být dynamicky rekonfigurovány tak, aby se přizpůsobily proměnlivému vytížení. [50] Cloud computing je obecně poskytování různých služeb přes internet nebo intranet, přičemž tyto služby běží na virtuální infrastruktuře poskytovatele. Pro přístup k těmto službám postačí internetový prohlížeč, přes který se uživatel připojí ke cloudu poskytovatele. [39] Data i aplikační logika jsou uloženy a provozovány na straně poskytovatele služeb a poskytované služby jsou pro všechny uživatele stejné. [19] Podle typu služby, kterou cloud computing poskytuje, rozlišujeme IaaS, PaaS a SaaS: [39] Infrastruktura jako služba (IaaS – Infrastructure as a Service) – Poskytnutí služby komplexní IT infrastruktury podle potřeb zákazníka. Zá18
http://www.ietf.org/rfc/rfc4287.txt http://www.iana.org/assignments/link-relations/link-relations.xml 20 http://www.opencloudmanifesto.org 19
19
3. Technologické řešení
Obrázek 3.3: Vývoj dodávky ICT služeb [3]
kazník pro podporu svého podnikání nemusí nakupovat servery, datová úložiště a síťové prvky a spravovat je vlastními silami. — příklady: Amazon EC2, Rackspace Cloud, Windows Azure Virtual Machines Platforma jako služba (PaaS – Platform as a Service) – Tento typ služby poskytuje kompletní prostředky pro provoz interních aplikací a vývojové prostředí dostupné přes internetový prohlížeč. Není třeba mít vlastní servery, vývojářský software, databáze a jejich správce. — příklady: Google App Engine, Heroku, Windows Azure Software jako služba (SaaS – Software as a Service) – Zákazník si pronajímá pro svoji potřebu aplikace třetích stran. Nemusí tak řešit nákup softwaru, licence ani aktualizace – vše zajistí poskytovatel služby. — příklady: Google Apps, Microsoft Office 365 Z rozdělení cloud computingu vyplývá jeho přínos v oblasti provozu IT služeb: • testování na různých platformách, • využití záložní kapacity nebo výpočetní síly pro vlastní IT služby v předvídaných špičkách, • provoz základních služeb jako jsou kancelářské aplikace či e-maily, • přenesení rizika na třetí stranu [39] – co vše spravuje poskytovatel a co uživatel zobrazuje Obrázek 3.4. Výhodou cloudu je téměř okamžité pořízení potřebné kapacity (v rámci několika minut či hodin) a zpoplatnění pouze využitého času, paměti, úložiště či přenesených dat. Nevýhodou je zejména centralizace moci a informací u jediného poskytovatele, teoreticky i bezpečnost (faktem je, že velká centrální úložiště bývají zabezpečena lépe než jednotlivé počítače či servery společností). [39]
3.2.1
Heroku
V diplomové práci budu využívat služeb jednoho z nejznámějších cloud hostingů – Heroku21 . Skutečnost, že se jedná o velkého poskytovatele PaaS, potvr21
20
http://www.heroku.com
3.2. Cloud computing
Obrázek 3.4: Rozdělení cloud computingu[16]
zuje fakt, že jej v roce 2010 koupila společnost Salesforce.com22 za 212 miliónů dolarů. [38] Heroku umožňuje vyzkoušet své služby zdarma, takže se není třeba obávat žádných poplatků. Po nainstalování programu Heroku Toolbelt23 můžeme z prostředí Git klienta používat příkaz heroku pro ovládání svého účtu. Vytvoření nové aplikace je jednoduché: 1. vygenerujeme privátní a veřejný klíč: ssh-keygen -t rsa, 2. přihlásíme se k účtu u Heroku vyplněním e-mailu a hesla: heroku login, 3. odešleme veřejný SSH klíč Heroku: heroku keys:add, 4. vytvoříme novou aplikaci: heroku create, 5. odešleme zdrojové kódy na server: git push heroku master, 6. nastavíme počet Heroku dynos: heroku ps:scale web=1, 7. definujeme prostředí: heroku config:add NODE_ENV=production. 22 23
http://www.salesforce.com https://toolbelt.heroku.com
21
3. Technologické řešení Kroky 1 a 3 je třeba provést pouze při zakládání nového účtu. Kroky 4, 6 a 7 stačí provést pouze jednou u každé nově vytvořené aplikace. Příkaz heroku ps:scale web=1 nastavuje počet běžících Heroku web dynos24 na 1, což je maximální počet, který je zdarma – každý další dyno stojí 35 dolarů měsíčně (k jedné aplikaci je možné jich využít až 100). Aby tento příkaz fungoval, je třeba mít v kořeni aplikace soubor Procfile, kde se definuje proces, který se má spustit. Obsah tohoto souboru může vypadat např. takto: web: node myapp.js. Krok 7 definuje prostředí, díky čemuž bude Heroku vědět, že má sledovat nastavení v sekci production (kde může být např. definováno připojení k produkční databázi).
3.2.2
MongoLab
Heroku umožňuje využít databázi zcela zdarma, přesto je ale nutné pro její zřízení zadat informace o platební kartě. Pokud se někomu nechce zadávat informace o platební kartě, existuje skvělá alternativa – MongoLab25 . MongoLab je stejně jako Heroku poskytovatelem PaaS, sám se označuje konkrétně jako MongoDB as a Service. Zdarma umožňuje využít pro každou databázi až 500 MB a navíc si můžeme vybrat, kdo bude jejím skutečným poskytovatelem: Amazon Web Services, Joyent Cloud, Rackspace či Windows Azure.
3.3
HTML5
HTML (HyperText Markup Language) je značkovací jazyk pro definování struktury stránek na webu. HTML5 je připravovaná specifikace, která by v budoucnu měla nahradit aktuálně používané specifikace HTML 4.01 a XHTML 1.0. Konečná specifikace HTML 5.0 by měla být schválena konsorciem W3C26 (World Wide Web Consortium) do konce roku 2014. [52]
3.3.1
Historie HTML
První definici jazyka HTML vytvořil v roce 1991 Tim Berners-Lee jako součást projektu WWW, který měl umožnit fyzikům a jiným vědcům komunikovat a sdílet výsledky výzkumů po celém světě. Ne náhodou proto celý projekt vznikal v CERNu (Centre Européenne pour la Recherche Nucléaire, Evropské centrum jaderného výzkumu). [22] Neoficiální verze HTML+ byla představena v druhé polovině roku 1993. HTML+ obsahovalo 78 elementů, z nichž mnohé již 24
Heroku nabízí 2 typy dynos: web dynos a worker dynos. Oba typy umožňují horizontální škálování. Více web dynos umožní obsloužit současně větší množství HTTP požadavků. Worker dynos provádí procesy na pozadí, takže jejich přidáním lze zlepšit výpočetní výkon aplikace. 25 https://mongolab.com 26 http://www.w3.org
22
3.3. HTML5 dnes v HTML nenajdeme. Tyto elementy definovaly komponenty dokumentů, např. výpisky, poznámky a podtitulky. [44] HTML 2.0, uvedené v roce 1994, bylo první verzí, která měla formální specifikaci a stala se oficiálním standardem přijatým konsorciem W3C. Tato verze obsahovala 49 elementů. V březnu 1995 bylo specifikováno HTML 3.0. Zde se poprvé objevily tabulky, možnost obtékání obrázků textem, matematické elementy či atributy elementu FORM. [44] V květnu 1996 bylo uvedeno HTML 3.2, které se považuje za pravého nástupce HTML 2.0. HTML 3.2 přidalo 19 nových prvků, zachovalo tabulky a atributy pro obtékání textu z HTML 3.0 a zapracovalo četná rozšíření pro prohlížeče Netscape Navigator. [44] HTML ve verzi 4.0 se během jejího vývoje přezdívalo Cougar. Přidala podporu prvku OBJECT, který má velký význam pro vkládání obrázků a multimédií. Dále HTML 4.0 podporuje kaskádové styly, úpravy formulářů a tabulek, skriptování na straně klienta či internacionalizaci (tj. rozpoznání jazyků, které obsahují zvláštní znaky v abecedě nebo se čtou zprava doleva). [44] HTML 4.0 bylo přijato jako standard W3C v prosinci roku 1997. Poté se vývoj jazyka na poměrně dlouhou dobu v podstatě zastavil. [22] V prosinci 1999 byl vydán nový standard HTML 4.01, který pouze opravil některé drobné chyby v předchozí specifikaci. Protože v roce 1998 zveřejnilo W3C jako standard jazyk XML, který se záhy stal velmi populárním formátem pro výměnu a ukládání dat, byla v roce 2000 vydána specifikace XHTML 1.0, která měla svoji syntaxi odvozenou právě od XML. Značky zůstaly v zásadě stejné, pouze se drobně změnila syntaxe. [22] Zdálo se, že XHTML by mohla být ta správná technologie nejen pro klasický web, a tak vznikly jeho speciální zjednodušené verze – XHTML Basic pro mobilní zařízení a XHTML Print pro jednoduché tiskové výstupy. XHTML 1.1 z roku 2001 v návaznosti na to nově popisovalo mechanismus modularizace celého jazyka a vytváření vlastních odvozenin. [22] XHTML ve verzi 1.0 ani 1.1 nepřidalo oproti HTML 4.01 v podstatě žádnou novou funkčnost, proto se začala na půdě W3C vyvíjet verze XHTML 2.0, která by přinesla mnohé zajímavé vlastnosti. Tato verze by nebyla plně kompatibilní s předchozími verzemi, čímž se W3C dostalo do sporu s výrobci prohlížečů – ti nakonec v roce 2004 sami založili pracovní skupinu WHATWG27 (The Web Hypertext Application Technology Working Group), na jejíž půdě pak společně připravovali specifikaci platformy pro webové aplikace běžící v prohlížeči. Po dlouhých jednáních nakonec i uvnitř W3C převážil názor, že XHTML 2 je slepá cesta, a v roce 2007 se proto síly W3C a WHATWG spojily. Pracovní skupina HTML vzala jako základ specifikace Web Forms 2.0 a Web Applications 1.0 vytvořené ve WHATWG a na jejich základě začalo vznikat HTML5. [22] 27
http://www.whatwg.org
23
3. Technologické řešení
Obrázek 3.5: Chování mobilního prohlížeče Safari v závislosti na typu vstupního pole [21] Tabulka 3.1: HTML5 – podpora formulářových atributů v prohlížečích [27]
autocomplete autofocus list min max multiple pattern placeholder required step
3.3.2
Firefox 11 3 3 3 7 7 3 3 3 3 7
Opera 11.62 3 3 3 3 3 3 3 3 3 3
Chrome 18 3 3 7 3 3 3 3 3 3 3
Safari 5.1 7 3 3 3 3 3 3 3 3 3
6 7 7 7 7 7 7 7 7 7 3
IE 7 8 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7
9 7 7 7 7 7 7 7 7 7 7
Web Forms 2.0
Web Forms 2.0 je specifikace pro rozšíření webových formulářů. Tato specifikace usnadňuje vývojářům tvorbu formulářů bez JavaScriptu a pro uživatele zvyšuje použitelnost (příklad lepší použitelnosti demonstruje Obrázek 3.5). HTML5 v rámci této specifikace přináší do formulářů nové atributy (autocomplete, autofocus, placeholder, required aj.), nové typy vstupních polí (number, range, email, url, tel, search, color, date aj.) a nový element datalist. Atribut placeholder slouží k vepsání textové nápovědy do pole (např. v poli pro vyhledávání může být vepsáno šedivě „Hledaný výraz“) – tato textová nápověda po kliknutí do pole zmizí. Element datalist je v podstatě 24
3.3. HTML5 Tabulka 3.2: HTML5 – podpora typů vstupních polí v prohlížečích [27]
search tel url email datetime date month week time localtime number range color
Firefox 11 3 3 3 3 7 7 7 7 7 7 7 7 7
Opera 11.62 3 3 3 3 3 3 3 3 3 3 3 3 3
Chrome 18 3 3 3 3 7 7 7 7 7 7 3 3 7
Safari 5.1 3 3 3 3 7 7 7 7 7 7 3 3 7
6 7 7 7 7 7 7 7 7 7 7 7 7 7
IE 7 8 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7
9 7 7 7 7 7 7 7 7 7 7 7 7 7
jakási forma našeptávání, ale s tím rozdílem, že všechny možné termíny jsou napovězeny uživateli okamžitě při kliknutí do pole a ne až po vepsání určitého množství znaků. [21] Význam ostatních atributů a typů je z názvu samovysvětlující. Podporu formulářových atributů a typů vstupních polí v nejběžnějších prohlížečích zobrazuje Tabulka 3.1 a 3.2.
3.3.3
Web Applications 1.0
Specifikace HTML 4.0 i pozdější XHTML 1.0 byly vytvořeny v době, kdy na webu převládal statický obsah. Současná etapa webu, Web 2.0, je naproti tomu daleko dynamičtější, neboť do tvorby obsahu jsou vtaženi samotní uživatelé. Na dnešním webu tak nalezneme nespočet blogů, fór, diskusí či internetových obchodů. Problémem obou výše zmíněných specifikací je fakt, že pouze definují strukturu dokumentu, ale již nijak neovlivňují funkcionalitu. To ostatně vyplývá z historického kontextu. Proto vzniká specifikace HTML5, aby pokryla nejčastější současné problémy, zjednodušila práci vývojářům a přinesla užitek uživatelům webu. [13] Hlavní změny zahrnují tyto oblasti: • multimédia – podpora audia a videa, • sémantika – nové elementy (použití viz Obrázek 3.6), změna významu některých již existujících elementů, podpora mikrodat, • práce s daty – File API pro práci se soubory, AppCache pro tvorbu aplikací offline, WebStorage pro ukládání dat, 25
3. Technologické řešení
Obrázek 3.6: Struktura blogu podle HTML4 a HTML5 [25]
• zvýšení výkonu – Page Visibility API pro efektivní „operování“ se stránkou, WebWorkers pro multithreading • a mnoho dalších (viz Tabulka 3.3). V diplomové práci budu vytvářet single-page AJAXovou aplikaci, proto využiji HTML5 History API, které mi umožní manipulovat s historií navštívených stránek a hlídat změny URL fragmentu. Použití HTML5 je nutností i z toho důvodu, že aplikace bude postavená na CSS frameworku Bootstrap, který HTML5 přímo vyžaduje. O frameworku Bootstrap bude pojednáno více v následující kapitole.
3.4
CSS3
CSS (Cascading Style Sheets) je jazyk pro popis způsobu zobrazení stránek napsaných v jazycích HTML, XHTML nebo XML. První verze jazyka, CSS1, byla specifikována konsorciem W3C v roce 1996. Druhá verze, CSS2, byla standardizována v roce 1998. Práce na CSS2.1 trvala řadu let. V roce 2004 bylo CSS2.1 ve stavu Candidate Recommendation (CR), rok na to se vrátilo do původního stavu Working Draft (WD). V roce 2007 opět postoupilo do stavu CR, aby se v roce 2010 zase (tentokrát již naposledy) vrátilo do stavu WD. Konečného stavu W3C Recommendation (REC) dosáhlo CSS2.1 nakonec až v dubnu 2011. Poslední verze jazyka, CSS3, je na rozdíl od předchozích verzí rozdělena do modulů. Ty se nacházejí v různých stavech, přičemž většina je ve stavu WD. Moderní prohlížeče ovšem již dnes velké množství nových vlastností podporují. 26
3.5. JavaScript Tabulka 3.3: HTML5 – podpora Web Applications v prohlížečích [27]
Web Storage Message Offline Apps Workers Query Selector WebSQL DB IndexDB DB Drag and drop Hash change History mgmt WebSockets GeoLocation Touch File API Meter element Progress bar
Firefox 11 3 3 3 3 3 7 7 3 3 3 3 3 7 3 7 3
Opera 11.62 3 3 3 3 3 3 7 7 3 3 7 3 7 3 3 3
Chrome 18 3 3 3 3 3 3 3 3 3 3 3 3 7 3 3 3
Safari 5.1 3 3 3 3 3 3 3 3 3 3 3 3 7 7 7 7
6 7 7 7 7 7 7 7 3 7 7 7 7 7 7 7 7
IE 7 8 7 3 7 3 7 7 7 7 7 3 7 7 7 7 3 3 7 3 7 7 7 7 7 7 7 7 7 7 7 7 7 7
9 3 3 7 7 3 7 7 3 3 7 7 3 7 7 7 7
V diplomové práci použiji CSS framework Bootstrap28 , za kterým stojí společnost Twitter. Aktuálně se jedná o nejsledovanější projekt na GitHubu, což potvrzuje jeho širokou oblíbenost. Bootstrap umožňuje velmi jednoduše vytvářet funkční a použitelný frontend webové aplikace. Má podporu ve všech běžných prohlížečích, včetně staršího Internet Exploreru 7. Bootstrap je často označován jako CSS framework, ale jedná se o kolekci obsahující i JavaScript – konkrétně obsahuje řadu pluginů JavaScriptové knihovny jQuery.
3.5
JavaScript
JavaScript je multiplatformní objektově orientovaný skriptovací jazyk, který byl standardizován v roce 1997 asociací ECMA (European Computer Manufacturers Association). Standardizovaná verze JavaScriptu nese proto název ECMAScript. ECMAScript ve verzi 3 vzniknul na konci roku 1999, verze 5 byla publikována v roce 2009. [47] JavaScript se používá zejména jako interpretovaný programovací jazyk pro webové stránky. Interpretace jazyka může probíhat v prohlížeči (v takovém případě mluvíme o client-side JavaScriptu), nebo na straně serveru (potom mluvíme o server-side JavaScriptu). 28
http://twitter.github.com/bootstrap
27
3. Technologické řešení JavaScript je dynamicky typovaný jazyk, což znamená, že typová kontrola je prováděna za běhu a proměnná může ukazovat na hodnotu jakéhokoli typu. Zároveň se jedná o slabě typovaný jazyk, takže typy se implicitně převádí (nebo přidělí) při použití.
3.5.1
Objekty
JavaScript je objektově orientovaný jazyk, proto vše, co není primitivní typ, je objekt. Primitivních typů je pouze pět: číslo, řetězec, boolean hodnota, null a undefined. První tři typy ovšem existují i v objektové reprezentaci. Objekt je kolekce pojmenovaných vlastností – seznam dvojic klíč – hodnota. Svým uspořádáním se tak podobá asociativnímu poli. [47] Objekt může být funkce, pole nebo třeba i regulární výraz, je to zkrátka vše, co umožňuje přiřadit vlastnost a předává se referencí. V JavaScriptu existuje samostatný typ Object, který je v hierarchii všech typů nejvýše, je předkem pro všechny ostatní typy a jeho potomci tudíž dědí jeho vlastnosti. [48] Jeho nejdůležitější vlastností je vlastnost prototype, o které bude pojednáno více v Kapitole 3.5.2. Objekty můžeme rozdělit na nativní a hostitelské: • nativní objekty – jsou popsány standardem ECMAScript (Boolean, Date, Function, Number aj.), • hostitelské objekty – jsou definovány prostředím, ve kterém JavaScript běží, tedy např. prohlížečem (document, window, console aj.). Nativní objekty můžeme dále rozdělit na vestavěné (např. Array, Date) nebo definované uživatelem (např. var o = {};). [47] Objekt, ve kterém voláme nějakou funkci, nazýváme kontext a odkazujeme se na něj přes klíčové slovo this. Výpis kódu 3.2: Deklarace třídy 1 2 3
var Animal = function ( name ) { this . name = name ; };
4 5 6 7 8 9
Animal . prototype = { getName: function () { return this . name ; } };
10 11 12 13
28
// vytvoreni instance var myDog = new Animal ( " Harry " ) ; console . log ( myDog . getName () ) ; // Harry
3.5. JavaScript
3.5.2
Třídy
JavaScript nemá „klasické třídy“, což dělá jeho kód kratší, protože nepotřebujeme třídu, abychom vytvořili objekt. [47] Mezi programátory JavaScriptu platí konsensus, že za třídu považujeme konstrukční funkci, zkráceně konstruktor, který využívá vlastnosti prototype. [48] Přestože lze nasimulovat třídu více způsoby, přirozenou deklaraci třídy zachycuje Výpis kódu 3.2. Jak je vidět, statické vlastnosti (zde name) a metody přiřazujeme konstruktoru, zatímco instanční metody (zde getName()) definujeme v prototype. Definování instančních metod v prototype má tu výhodu, že tak můžeme jednoduše změnit instance i poté, co byly vytvořeny, viz Výpis kódu 3.3. Výpis kódu 3.3: Změna instance 1 2 3
Library . Animal . prototype . getName = function () { // novy kod };
Pokud bychom instanční metodu definovali v konstruktoru, každá instance Animal by přepsala metodu getName() z Animal.prototype a oprava z vnějšku by byla nemožná. [48] Vlastnost prototype se využívá také při implementaci dědičnosti, mluvíme proto o prototypové dědičnosti.
3.5.3
Scope, closure a hoisting
Scope je rozsah viditelnosti proměnné. Může být globální nebo lokální. Globální scope je jeden a v prohlížeči jej vždy reprezentuje objekt window. Lokální scope generuje pouze funkce. JavaScript umožňuje do sebe funkce zanořovat, čímž vytváříme scope chain. [48] Closure (viz Výpis kódu 3.4) nějaké funkce je scope, ve kterém byla funkce deklarována (tj. vnější scope funkce). Closure funkce je důležitý, protože je na něj „vidět“, ať už voláme funkci z jakéhokoliv místa programu. Zanořování funkcí a to, že každá funkce má vlastní closure, jsou funkcionální prvky jazyka JavaScript. [48] Výpis kódu 3.4: Closure 1 2 3 4 5 6 7 8 9
var getCount = function ( start ) { var number = start ; // promenna number ulozena v closure return function () { console . log ( number ++) ; }; }; var counter = getCount (1) ; counter () ; // 1 counter () ; // 2
29
3. Technologické řešení Hoisting (též variable hoisting) je způsob interpretace kódu JavaScriptu. Princip je takový, že interpret při zpracování těla funkce nalezne všechny identifikátory lokálních proměnných deklarovaných pomocí klíčového slova var a „vyzdvihne“ je na začátek těla funkce. [1] To znamená, že Výpis kódu 3.5 se ve skutečnosti vyhodnotí jako Výpis kódu 3.6. Do konzole se tak nevypíše ani 1, ani 2, nýbrž undefined. Na toto chování je třeba myslet, a proto se doporučuje vždy deklarovat všechny lokální proměnné na začátku funkce. Výpis kódu 3.5: Hoisting 1 1 2 3 4 5 6
var variable = 1; function attempt () { console . log ( variable ) ; // undefined var variable = 2; } attempt () ;
Výpis kódu 3.6: Hoisting 2 1 2 3 4 5 6 7
var variable = 1; function attempt () { var variable ; console . log ( variable ) ; // undefined variable = 2; } attempt () ;
3.5.4
jQuery
jQuery29 je JavaScriptová knihovna s širokou podporou prohlížečů, která klade důraz na interakci mezi JavaScriptem a HTML. Tato knihovna byla vydána v lednu 2006 a okamžitě se stala velmi populární. V dnešní době tak na internetu nalezneme stovky pluginů, které tuto knihovnu využívají. jQuery obsahuje funkce zejména pro základní DOM a CSS manipulace, události, utility, efekty, animace, AJAX a podporu pluginů. Přitom se maximálně vyhýbá znečištění globálního scope, takže má pouze dvě globálně viditelné proměnné, jQuery a znak dolaru ($). [48] Protože $ používá mnoho dalších JavaScriptových knihoven, doporučuje se vlastní kód patřičně zapouzdřit (viz Výpis kódu 3.7).30 Výpis kódu 3.7: Zapouzdření jQuery kódu 1 2 3
( function ($) { // kod pouzivajici $ }) ( jQuery ) ;
29 30
30
http://jquery.com http://docs.jquery.com/Using_jQuery_with_Other_Libraries
3.5. JavaScript
Obrázek 3.7: Zkušenosti Bena Nadela s AngularJS [32]
3.5.5
AngularJS
AngularJS31 je JavaScriptový open-source MVC framework vyvíjený společností Google. Jeho hlavními tvůrci jsou Vojta Jína (někdejší student ČVUT), Igor Minar a Miško Hevery – s trochou nadsázky se dá říci, že se jedná v podstatě o Česko-Slovenský projekt. Počáteční dojmy z frameworku AngularJS mohou být rozpačité. Zkušenosti Bena Nadela, zakladatele společnosti Epicenter Consulting32 , znázorňuje Obrázek 3.7. [32] S jeho pohledem na začátky s frameworkem se plně ztotožňuji. Mezi nejužitečnější koncepty AngularJS patří: • Two-Way Data-Binding, • Dependency Injection, • testovatelnost, • direktivy. Two-Way Data-Binding33 Koncept two-way data-binding řeší synchronizaci stavů mezi modelem a view. Do češtiny bychom mohli tento pojem přeložit jako „dvoucestná synchronizace dat“. [31] 31
http://angularjs.org http://www.epicenterconsulting.com 33 http://docs.angularjs.org/guide/dev_guide.templates.databinding 32
31
3. Technologické řešení
Obrázek 3.8: One-Way Data-Binding [4]
Obrázek 3.9: Two-Way Data-Binding [4]
Většina šablonovacích systémů provádí data-binding pouze v jednom směru – v takovém případě se komponenty šablony a modelu sloučí do jednoho view, jak znázorňuje Obrázek 3.8. Jakékoliv změny, které pak uživatel provede ve view, nejsou reflektovány do modelu. Vývojář tak musí psát množství kódu, který zajistí oboustrannou synchronizaci mezi modelem a view. V AngularJS fungují šablony odlišně, a to zejména ze 2 důvodů: 1. šablona (HTML kód doplněný o direktivy) je „kompilována“ až v prohlížeči, 2. kompilace produkuje view, které je do značné míry dynamické. View je dynamické, protože všechny změny ve view se okamžitě projeví v modelu a jakékoliv změny v modelu se stejně tak projeví ve view. Model je považován za Single Source of Truth 34 , díky čemuž je controller od view dokonale odstíněn. Výhodou odstínění controlleru od view je pak mimo jiné zjednodušení testování. 34 Pravidlo Single Source of Truth (SSOT) říká, že by měl existovat právě jeden centrální zdroj informací, který je považován za objektivní.
32
3.5. JavaScript Způsob implementace konceptu two-way data-binding je deklarativní, programátor tak nemusí imperativně popisovat, jak data synchronizovat. Namísto toho pouze deklaruje vztah a AngularJS zajistí synchronizaci. [31] Deklarativní implementace je nejen rychlejší, je také mnohem čitelnější pro programátora, který projekt případně převezme. Interní realizace data-bindingu v Angularu je autory označována jako dirty checking. Tato realizace je dost odlišná od způsobu, jakým data-binding řeší jiné frameworky (Ember.js, Knockout.js nebo třeba Backbone.js), v benchmarkingu si však stojí všechny frameworky víceméně podobně. Dependency Injection Dependency Injection 35 (DI) je návrhový vzor, který slouží pro snížení závislostí mezi jednotlivými částmi systému. Jeho provedení vychází z obecnějšího návrhového vzoru Inversion of Control (IoC). DI je pojem, který poprvé představil Martin Fowler ve svém článku Inversion of Control Containers and the Dependency Injection pattern 36 . [43] Existují pouze tři způsoby, jak objekty a funkce mohou přijít k závislosti: 1. závislost může být vytvořena – typicky použitím operátoru new, 2. závislost může být navázána – odkazováním na globální proměnnou, 3. závislost může být vložena tam, kde je zapotřebí. [5] První dvě možnosti nejsou optimální, protože závislosti definují způsobem, který se běžně označuje jako „hard coding“. V takovém případě je velmi obtížné závislosti později změnit a testování se stává obtížné, neboť je zapotřebí vytvořit řadu mock objektů, abychom tyto závislosti odstínili. Třetí možnost je nejschůdnější a je to cesta, kterou se vydal i framework AngularJS. Ten obsahuje zabudovaný subsystém, který řeší DI napříč celou vyvíjenou aplikací. Umožňuje vždy přesně specifikovat, které komponenty jsou uvnitř jiné konkrétní komponenty používané. Refaktoring aplikace je tak velmi jednoduchý. Na následujících řádcích ukáži, jak konkrétně funguje implementace DI. Definice jednoduchého controlleru zachycuje Výpis kódu 3.8. Controlleru se při vytvoření předávají 2 parametry, přes které se předávají závislosti. Uvnitř controlleru se nepracuje s ničím jiným než právě s těmito závislostmi. Tyto závislosti se nazývají services (služby) a mohou být dvojího druhu: 1. interní, které jsou dodávány přímo s frameworkem a prefixují se znakem dolaru ($), 2. vlastní, které si vývojář definuje sám. 35 36
http://docs.angularjs.org/guide/di http://martinfowler.com/articles/injection.html
33
3. Technologické řešení Výpis kódu 3.8: Definice controlleru 1 2 3 4 5 6
function MyController ($ scope , myService ) { $ scope . sayHello = function () { myService . greet ( " Hello World " ) ; }; } injector . instantiate ( MyController ) ;
Znak dolaru pro interní služby se používá proto, aby nevznikl konflikt mezi proměnnými přidanými vývojářem a proměnnými přidanými frameworkem. Interní služba $scope řeší kontext dat a je důležitá pro koncept data-bindingu. Služba myService je vlastní a jejím cílem je v tomto případě vypsat pozdrav v dialogovém okně. Definici služby pomocí faktory metody demonstruje Výpis kódu 3.9. Faktory metody jsou využívány k vytvoření většiny objektů v AngularJS. Vytváří se jimi tedy nejen služby, ale například i direktivy či filtry. Výpis kódu 3.9: Definice služby 1 2 3 4 5 6 7 8
angular . module ( " myModule " , []) . factory ( " myService " , function ($ window ) { return { greet: function ( text ) { $ window . alert ( text ) ; } }; }) ;
9 10 11
var injector = angular . injector ([ " myModule " , " ng " ]) ; var myService = injector . get ( " myService " ) ;
Vypsání pozdravu by se provedlo po kliknutí na tlačítko v šabloně, viz Výpis kódu 3.10. Takováto realizace je v souladu s Deméteřiným zákonem 37 , neboť zodpovědnost za vytvoření závislostí přejímá injector. Výpis kódu 3.10: Aplikace direktivy 1 2 3
< div ng - controller = " MyController " > < button ng - click = " sayHello () " > Hello button > div >
V případě minifikace nebo obfuskace kódu v definici controlleru by Výpis kódu 3.8 nefungoval, neboť parametry musí být stejného názvu jako injektované služby. Toto lze obejít anotací $inject, jak ukazuje Výpis kódu 3.11. 37
Deméteřin zákon (Law of Demeter, LoD) definuje omezení, s jakými objekty může objekt přímo komunikovat a s jakými ne. Zákon se někdy parafrázuje jako „rozmlouvej s přáteli, ne s cizinci“.
34
3.5. JavaScript Výpis kódu 3.11: Anotace $inject 1 2 3 4
var MyController = function ( renamed $ scope , renamedMyService ) { // ... } MyController .$ inject = [ " $ scope " , " myService " ];
Testovatelnost AngularJS je zaměřen na testovatelnost kódu, k čemuž přispívá zejména implementace DI a mnohé nástroje pro testování, které díky frameworku vznikly. Jedná se např. o projekt Karma38 (dříve nazývaný Testacular), který umožňuje automatizovaně spouštět testy nad různými prohlížeči, či jasmine-node39 , který přenesl jeden z nejoblíbenějších JavaScriptových testovacích frameworků Jasmine do prostředí Node.js. [31] Běh testů je velmi rychlý – Vojta Jína demonstroval na několika konferencích vyhodnocení téměř 1 600 unit testů za dobu kratší než 3 vteřiny. Při vytváření nové aplikace je výhodné použít jako výchozí šablonu angularseed40 , která obsahuje předpřipravené prostředí pro jednotkové a end-to-end testy. Direktivy Direktivy umožňují vývojáři specifikovat vlastní HTML kód doplněný o takřka libovolnou funkcionalitu. Direktivou může být: • element: <my-directive> • atribut:
• komentář: Kromě vytváření vlastních direktiv můžeme využít také řadu již předpřipravených direktiv, např.: ngApp – Automaticky spustí aplikaci. Jako parametr očekává název hlavního modulu aplikace. ngModel – Direktiva, která říká, že se má použít two-way data-binding. Veškeré změny ve scope se promítnou na tomto elementu a naopak, veškeré změny hodnoty vázaného elementu se projeví ve scope. Funguje pouze s elementy input, select a textarea. [11] 38
https://github.com/karma-runner/karma http://github.com/mhevery/jasmine-node 40 http://github.com/angular/angular-seed 39
35
3. Technologické řešení ngBind – Automaticky změní text uvnitř HTML elementu na hodnotu danou výrazem. ngRepeat – Direktiva, pomocí které můžeme procházet kolekci. V rámci cyklu pak můžeme využívat číselnou proměnnou $index a boolean proměnné $first, $middle a $last. ngController – Předá danému elementu scope controlleru. Tato direktiva byla představena již ve Výpisu kódu 3.10.
3.6
Node.js
Node.js41 je platforma pro psaní vysoce škálovatelných internetových aplikací v jazyce JavaScript. Tuto platformu vytvořil v roce 2009 Ryan Dahl a díky ní je možné JavaScript používat i na serveru a vytvářet aplikace podobně jako třeba v PHP, Javě, Ruby nebo Pythonu. Alternativou k Node.js by v tomto ohledu byly např. Jaxer či částečně i Rhino. Pojem platforma zahrnuje i webový server, takže není potřeba k Node.js instalovat zvláštní webový server. V produkčním nasazení je nicméně lepší Node.js používat společně s jiným webovým serverem, který např. zajistí přístup ke statickým souborům (styly, obrázky apod.). Velmi často se pro tyto účely používá populární server nginx. [28] Node.js je postaven na JavaScriptovém enginu V8, který pohání internetový prohlížeč Google Chrome. Navíc ale obsahuje tenkou vrstvu kódu v C++ poskytující minimální nutné zázemí (event-loop vyhodnocující příchozí události, obsluha I/O bufferů a jiné). [34] JavaScript se do C++ také kompiluje, takže je velmi rychlý, i když funguje pouze v jednom vlákně. Protože Node.js pracuje pouze v jednom vlákně, před zpracováním prvního HTTP požadavku dojde k načtení a inicializaci všeho potřebného. Jakmile je vše načteno, Node.js poslouchá příchozí požadavky, které směřuje na konkrétní controllery. Požadavky jsou přitom obsluhovány v pořadí, v jakém na server přicházejí. [28] Node.js používá událostmi řízený (event-driven) neblokující IO model, což znamená, že v případě zpracování konkrétního HTTP požadavku je zapotřebí používat výhradně asynchronní metody. [28] Použití synchronních metod by způsobilo zablokování celého serveru do doby, než by byly zpracovány. Všechny IO operace jsou proto v Node.js napsány neblokujícím způsobem. Dlouhotrvající operace je možné řešit např. spuštěním samostatného procesu přes balíček child_process, což je obdoba Web Workers z client-side JavaScriptu. Operace typu práce s databází, čtení a zápis se spouštějí na pozadí a ve vláknech tak, jak je to běžné i u ostatních jazyků. [28] 41
36
http://nodejs.org
3.6. Node.js
3.6.1
Výhody Node.js
Na Node.js staví své aplikace společnosti jako LinkedIn, eBay, Yahoo!, Mozilla či Walmart. Yahoo! si Node.js vybralo pro svůj JavaScriptový MVC framework Mojito. Podobně LinkedIn si vybralo Node.js pro novou mobilní aplikaci. Původně byla tato mobilní aplikace napsána v Ruby on Rails, po přechodu na Node.js však došlo k více jak desetinásobnému zrychlení. S Ruby on Rails používal LinkedIn 15 serverů s 15 virtuálními servery na každém fyzickém stroji. Po přechodu na Node.js jsou zapotřebí pouze čtyři virtuální servery, které zvládnou dvojnásobný provoz. [36] Výhody Node.js by se daly sumarizovat do několika bodů: • Díky Node.js lze pracovat s JavaScriptem na straně serveru. Stačí nám tak jeden programovací jazyk, protože JavaScript využijeme na serveru i u klienta. To znamená, že na serveru můžeme použít i oblíbené JavaScriptové knihovny, které již známe z dřívějška z klientského prostředí. Pokud navíc využíváme NoSQL databázi, vystačíme si s JavaScriptem úplně všude. • Drtivá většina knihoven v Node.js je napsána v JavaScriptu, takže knowhow lze dobře hledat přímo v kódu. Knihovny v jádru Node.js mají navíc jasné konvence pro pojmenování i pořadí parametrů. [30] • V Node.js je k dispozici vynikající balíčkovací systém npm (Node Package Manager), což je balíčkovací systém podobný RubyGems, jenž mnozí znají z Ruby. V současnosti je k dispozici ke stažení více než 20 tisíc knihoven. • JavaScript se kompiluje do C++ a je tedy velmi rychlý. • Node.js podporuje asynchronní architekturu, a umožňuje tak spouštět více operací najednou. • Komunita kolem Node.js v poslední době dramaticky roste. Samozřejmě samotné nasazení aplikace na Node.js není samospasné. Felix Geisendörfer, aktivní open-source programátor a zakladatel společnosti zabývající se poskytováním SaaS, sepsal základní případy užití, kde Node.js najde své uplatnění a kde naopak nikoliv. Node.js je podle něj vhodné použít, pokud chceme vytvářet tyto typy projektů: • light-weight aplikace s RESTful/JSON API, • single-page či real-time aplikace, • aplikace s podporou streamování dat. Naopak Node.js se podle něj nehodí pro projekty, které jsou velmi náročné na CPU, a pro jednoduché CRUD/HTML aplikace. [10] 37
3. Technologické řešení
3.6.2
Frameworky v Node.js
Frameworky v Node.js lze rozdělit do tří skupin: 1. inspirované světem Ruby – např. Express, RailwayJS či TowerJS, 2. určené pro real-time aplikace – např. Derby, SocketStream či Meteor, 3. ostatní – např. Flatrion, Mojito či Locomotive. [29] Nejpoužívanějším frameworkem je pravděpodobně Express, který je rozšířením frameworku Connect. Express umožňuje použít vše z frameworku Connect (ochrana proti CSRF, gzip komprese, HTTP autentizace, . . . ) a navíc přidává některé další praktické doplňky: • router, který umožňuje směrovat URL na konkrétní controllery a akce, • helper, např. pro odeslání různých hlaviček pro různé situace, • podporu pro šablonovací systémy. [29] Express, který budu v diplomové práci využívat, vytvořil TJ Holowaychuk. Kromě Expressu je TJ Holowaychuk autorem dalších více než 200 modulů, mnohdy velmi populárních: • Jade – oblíbený šablonovací systém, • Mocha – framework pro testování, • Supertest – modul užitečný pro integrační testování, • Should.js – modul pro asserty.
3.6.3
Balíčkovací systém npm
Balíčkovací systém npm42 je od verze 0.6.3 instalován spolu s Node.js automaticky. Nejedná se o jediného správce balíčků, ale je zdaleka nejpoužívanější. Za balíček (modul) můžeme považovat téměř cokoliv: jednoduchý skript, framework, testovací či jiný nástroj. Některé balíčky jsou součástí Node.js, ostatní si můžeme doinstalovat podle potřeby. Každý balíček se může skládat z dalších balíčků, jak je vidět např. na balíčku Express Resource:
[email protected] [email protected] [email protected] [email protected] 42
38
https://npmjs.org
3.7. Databáze Každý projekt či modul by měl obsahovat soubor package.json43 , který uchovává různé důležité informace, například: • název, verzi a autora, • popis a klíčová slova, • příznak, zda má být balíček instalován globálně či lokálně, • mapování příkazů na skripty (např. jaký skript se má spustit po zavolání npm test), • informace o repozitáři, • seznam závislostí na jiných balíčcích pro účely nasazení, vývoje a testování, • informace o licencování, • verzi vyžadovaného Node.js (např. >=0.6). Na základě tohoto souboru pak dojde zadáním příkazu npm install k nainstalování všech potřebných balíčků v konkrétních verzích – máme tak jistotu, že vše bude fungovat. Příkazy balíčkovacího systému npm npm npm npm npm npm npm npm npm
3.7
install :: instalace balicku podle package.json install nazev_balicku :: lok. instalace balicku uninstall nazev_balicku :: odinstalace balicku update nazev_balicku :: aktualizace balicku view nazev_balicku :: zobrazi detaily o balicku search libovolna_fraze :: vyhledavani balicku list :: zobrazeni vsech lok. balicku vc. zavislosti outdated :: vypise vsechny zastarale balicky
Databáze
U projektu s nutností ukládání dat stojí vývojář před nelehkou otázkou, jakou pro tyto účely využít databázi. Nejčastěji řešené dilema je, zda zvolit „SQL či NoSQL“. Toto dilema ovšem zahrnuje značné zjednodušení, a je tedy proto trochu zavádějící. Pod SQL (Structured Query Language) se v tomto případě nesprávně rozumí jakákoliv relační databáze (tedy ve smyslu engine, nikoliv jazyk využívaný pro práci s daty v relačních databázích). Pod NoSQL (někdy označovaném jako Not Only SQL) se označují všechny databázové enginy, které nejsou v souladu se zaběhnutými principy RDBMS (Relational Database Management System). [49] 43
http://package.json.nodejitsu.com
39
3. Technologické řešení Tabulka 3.4: Nejpoužívanější NoSQL databáze Název BigTable Cassandra CouchDB Memcache MongoDB Neo4J Riak Redis HBase
3.7.1
Datový model column family column family document key-value document graph key-value key-value column family
Open source 7 3 3 3 3 3 3 3 3
NoSQL
Výraz NoSQL poprvé použil Carlo Strozzi v roce 1998 pro pojmenování svého databázového systému, který nenabízel standartní SQL rozhraní pro přístup k datům. Tento termín získal ale na popularitě až v roce 2009, kdy se v San Franciscu konalo setkání velkých podporovatelů nerelačních DBMS (mezi zúčastněnými byly společnosti jako LinkedIn, Facebook aj.). [26] V současné době jsou NoSQL databáze nejčastěji charakterizovány přívlastky jako nerelační, distribuované, open-source a horizontálně škálovatelné. Často jsou charakterizovány také jako „bezschémové“, opatřené jednoduchým API, bez garance vlastností ACID (Atomicity, Consistency, Isolation, Durability) a schopné pojmout ohromné množství dat. [12] Samozřejmě ne všechny tyto vlastnosti platí pro všechny NoSQL databáze. Aktuálně existuje cca 150 NoSQL databází44 . Některé populární jsou uvedeny v Tabulce 3.4. CAP teorém V roce 2000 prezentoval Eric Brewer na ECM Symposiu svou teorii o třech požadavcích na distribuované systémy: 1. Consistency (konzistentnost) – všichni uživatelé databáze vidí ta samá data, 2. Availability (dostupnost) – vždy je možné získat nějakou verzi dat, 3. Partition tolerance (odolnost proti rozdělení) – databáze je schopna korektně fungovat, i když je přerušena komunikace mezi jednotlivými servery. [2] 44
40
http://nosql-database.org
3.7. Databáze
Obrázek 3.10: Rozdělení databázových systémů podle CAP teorému [15]
Tyto požadavky se v distribuovaném systému vzájemně vylučují, proto je možné si z nich zvolit pouze dva, které budou splněné. Rozdělení databází podle CAP teorému zobrazuje Obrázek 3.10. Z obrázku je patrné, že např. všechny relační databáze splňují konzistentnost a dostupnost, populární CouchDB splňuje dostupnost a odolnost proti rozdělení a MongoDB, která bude využita v rámci diplomové práce, volí konzistentnost a odolnost proti rozdělení. Jak vyplývá z CAP teorému, velké systémy nemohou garantovat vlastnosti ACID, proto jsou někdy charakterizovány zkratkou BASE: Basically Available – Systém garantuje dostupnost v souladu s CAP teorémem. Soft State – Stav systému se může v průběhu času měnit, dokonce bez vnějšího zásahu. To je způsobeno vlastností Eventually Consistent. Eventually Consistent – Systém se může uvést po určité době do konzistentního stavu. [14] 41
3. Technologické řešení
Obrázek 3.11: Skladba identifikátoru záznamu [24]
3.7.2
MongoDB
MongoDB je škálovatelná, vysoce výkonná NoSQL databáze. Jedná se o velmi populární databázi, o čemž svědčí i fakt, že dle statistik LinkedIn je ze všech NoSQL databází mezi uživateli této sítě nejpoužívanější.45 Struktura dat MongoDB ukládá data ve formátu BSON, což je binárně zakódovaný JSON. Data jsou ukládána v kolekcích, které jsou de facto obdobou tabulek v relačních databázích. Každá kolekce může obsahovat libovolný počet BSON dokumentů – proto mluvíme o dokumentově-orientované databázi. Při vytváření kolekce není potřeba explicitně uvádět její strukturu, což dělá MongoDB oproti RDBMS mnohem flexibilnější. Kolekce se automaticky vytvoří při prvním vložení dokumentu, který nesmí přesáhnout velikost 16 MB. Pokud je potřeba uložit větší soubor, používá se GridFS, což je mechanismus pro rozdělení velkého souboru mezi několik menších dokumentů, které pak vystupují jako jeden celek. Vedle klasických kolekcí máme možnost využít capped collections, což jsou kolekce, kterým můžeme nastavit maximální velikost. V případě dosažení této velikosti je pak při vkládání nejstarší záznam nahrazen novým. Tento typ kolekcí tak najde uplatnění například pro vedení logu. Podporované datové typy ukládaných hodnost jsou následující: číslo, řetězec, boolean hodnota, null, undefined, object id, datum, regulární výraz, JavaScriptový kód, pole, objekt a jiný vnořený dokument. Každý záznam v kolekci obdrží při vytvoření jednoznačný identifikátor _id – jedná se o 12bytový řetězec složený z data vložení, kódu stroje, kódu procesu a čísla (viz Obrázek 3.11). [24] Dotazování Komunikace s databází probíhá prostřednictvím JavaScriptu. MongoDB obsahuje funkce jako count(), distinct() či group(), jejichž význam je analogický k SQL. Pro aktualizaci dokumentu máme navíc k dispozici volbu upsert, která provede update, pokud dokument v databázi již je. V opačném případě je proveden insert. [24] 45
42
údaj z března 2013, viz http://www.linkedin.com/skills/skill/CouchDB
Kapitola
Analýza a návrh 4.1
Analýza požadavků
V rešerši byly představeny vybrané nástroje pro analýzu webové stránky. Některé nástroje provedly okamžitou analýzu po zadání požadované URL, jiné sbíraly informace o webové stránce v dlouhodobém horizontu a zcela nezávisle. Rešerše posloužila jako hodnotná inspirace pro určení možné funkcionality navrhované aplikace. Požadovaná funkcionalita bude popsána v následující části.
4.1.1
Funkční požadavky
Hlavní úlohou aplikace je provedení analýzy libovolné webové stránky. Uskutečnit analýzu bude možné prostřednictvím uživatelského rozhraní, stejně jako pomocí RESTful API. Uživatel bude mít možnost vykonávat i ostatní operace CRUD v souvislosti s provedenou analýzou. Analýza bude obsahovat informace týkající se technického zpracování stránek, obsahu, odkazového profilu, sociálních aktivit, vyhledávačů a rychlosti načítání. Neměl by chybět ani screenshot analyzované stránky. V následujícím textu budu používat zkrácené označení „test“, pod kterým se rozumí „analýza webové stránky“, případně „report z analýzy webové stránky“. Typ dokumentu – Uživatel bude upozorněn v případě, že typ dokumentu obsahuje slova Transitional, Frameset nebo Basic. XHTML Transitional je přechodným DTD pro webové stránky, který umožní používat překonané značky. XHTML Frameset umožňuje používat zastaralé značky a navíc přidává podporu pro rámce. Na XHTML Basic samo o sobě nemusí být nic špatného, ale uživatel by měl být konfrontován, zda skutečně chtěl použít DTD cílené zejména na mobilní aplikace. Znaková sada – Uživatel bude upozorněn v případě, že znaková sada není UTF-8. UTF-8 je nejčastějším zápisem znakové sady Unicode, která je 43
4
4. Analýza a návrh určena pro všechny světové jazyky najednou. Jde o nejmodernější kódování s vynikající podporou v prohlížečích. Naproti tomu např. kódování ISO 8859-1 (též Latin-1, Západoevropské ISO) neobsahuje všechny české znaky. Pokud by bylo použité na stránce v češtině, v zásadě by se jeho použití rovnalo chybě. Velikost HTML, CSS, JS a obrázků – Uživatel bude upozorněn v případě, že velikost HTML, CSS, JS nebo obrázků překročí stanovené limity (HTML 90 kB, CSS 90 kB, JS 190 kB, obrázky 1 MB). Datově náročná stránka prodlužuje dobu načítání a má neblahý vliv na Bounce rate – míru opuštění. Počet CSS a JS souborů – Uživatel bude upozorněn v případě, že stránka načítá víc jak 5 CSS nebo JS souborů. Každý soubor představuje další dotaz na server, čímž jsou na něj kladeny větší nároky. Ze stejného důvodu se z většího množství malých obrázků vytváří image sprites. Validita – Validita zdrojového kódu je okrajovým ukazatelem, který bývá často bagatelizován. V případě většího množství chyb však může renderování stránky v prohlížeči trvat delší dobu. Stejně tak velké množství závažných chyb s sebou nese riziko, že stránky vykreslí různé prohlížeče rozdílně. Stáří domény – Stáří domény má informativní charakter. Existují spekulace, že stáří domény a doba zbývající do její expirace jsou jistým způsobem v algoritmu vyhledávače Googlu zohledněny, ale Google nikdy nic podobného nepotvrdil (ačkoliv obojí zmiňuje ve svém patentu46 ). Jazyk stránky – Uživatel bude upozorněn v případě, že jazyk stránky nebyl rozpoznán. Název a popisek stránky – Uživatel bude upozorněn v případě, že název stránky (title) není v rozsahu 10 až 70 znaků. Stejně tak popis stránky (description) by měl být v rozsahu 50 až 200 znaků. Stejná funkcionalita je zahrnuta v Google Webmaster Tools. Výskyt testovaných klíčových slov – Klíčová slova, která uživatel zadal při odesílání formuláře pro vytvoření nového testu, budou hledána ve všech nadpisech a odstavcích. Report bude obsahovat počet výskytů slova napříč jednotlivými elementy a v rámci každého elementu (např. celkem: 5, z toho v H3: 1 a v odstavci: 4). Kontrola sémantiky – Uživatel bude upozorněn, pokud stránka obsahuje zanořené tabulky, rámce nebo je text zvýrazňován nesémantickými značkami (b, i). 46
44
http://www.google.com/patents/US20050071741
4.1. Analýza požadavků Počet slov – Uživatel bude upozorněn, pokud počet slov na stránce bude menší než 200. Do počtu slov nebudou započítávána stop slova odpovídající jazyku testované stránky (byl, bude, tyto, . . . ). Frekvenční analýza slov – Report bude obsahovat nejčastěji se vyskytující slova v textu. Mezi nejčastější slova nebudou zařazena stop slova odpovídající jazyku testované stránky. Stejná funkcionalita je zahrnuta v Google Webmaster Tools. Odkazový profil – Report bude obsahovat informace o počtu zpětných odkazů (celkem / z unikátních domén / z unikátních IP adres / z unikátních C sítí). Dále zobrazí počet odkazů vedoucích z webu s rozdělením externí/interní a follow/nofollow. Odkazy budou otestovány na odezvu a návratový kód. Uživatel bude upozorněn na odkazy s návratovým kódem 1xx, 4xx a 5xx. Sociální aktivity – Report bude obsahovat statistiky z oblasti sociálních sítí – počet +1 (sociální síť Google Plus), počet tweetů (sociální síť Twitter) a počet komentářů, „lajků“ a sdílení (sociální síť Facebook). Vliv sociálních aktivit na vyhledávání zmiňuje Google v Často kladených otázkách. Hovoří sice o +1, ale nelze vyloučit, že určitým způsobem zohledňuje i oblíbenost na konkurenčních soc. sítích. „Obsah doporučený přáteli a známými je často relevantnější než obsah doporučený někým cizím. Filmová recenze od experta může být například užitečná, ale recenze od přítele, který má podobný vkus, může být ještě lepší. Z tohoto důvodu mohou být hodnocení +1 od přátel a kontaktů pro Google užitečným faktorem při určování, zda je vaše stránka k dotazu uživatele relevantní. Toto hodnocení je však jen jedním z mnoha faktorů, pomocí kterých může Google posuzovat relevanci a hodnocení stránky. Náš algoritmus je navíc neustále upravován a vylepšován, abychom mohli nabídnout co nejvyšší celkovou kvalitu vyhledávání. U hodnocení +1, stejně jako u jakéhokoli jiného nového faktoru hodnocení, začínáme opatrně a budeme postupně zjišťovat, jak tyto faktory ovlivňují kvalitu vyhledávání.“ FAQ, Google [33]
Test rychlosti načítání stránek – Report bude obsahovat výstupy z testu rychlosti načítání stránek přes Google PageSpeed Insights API. Test bude proveden jak pro desktopovou, tak pro mobilní variantu. Informace týkající se vyhledávačů – Uživatel bude upozorněn, pokud není povolena indexace testované stránky. Report zároveň poskytne uživateli informace o počtu stran zaindexovaných Googlem a Seznamem k dané doméně a vypíše prvních 10 výsledků ze SERP. Report bude obsahovat informace o dosaženém PageRanku, S-ranku a Alexa Ranku. Uživatel 45
4. Analýza a návrh bude upozorněn, pokud neexistuje soubor robots.txt či mapa stránek (stejná funkcionalita je zahrnuta v Google Webmaster Tools).
4.1.2
Nefunkční požadavky
Některé nefunkční požadavky na aplikaci vyplývají přímo ze zadání, další požadavky jsou kladeny na výkon, uživatelské rozhraní a bezpečnost aplikace. Platforma – Použitou platformou bude Node.js. Hlavní výhoda této platformy spočívá v možnosti psaní asynchronního kódu. Můžeme tak např. současně získávat informace o testované stránce z různých externích zdrojů a po obdržení informací z posledního zdroje výsledek vrátit v odpovědi uživateli. Klientský framework – Webová prezentace bude napojena na framework AngularJS. Díky „kompilaci“ šablony v prohlížeči uživatele bude ušetřen výkon serveru. AngularJS navíc umožňuje efektivně využívat navržené RESTful API. Programovací jazyk – Vzhledem k použití platformy Node.js bude jako programovací jazyk použit JavaScript. Jeho výhody byly shrnuty v Kapitole 3.5. Databáze – Data budou ukládána do NoSQL databáze, konkrétně bude využita MongoDB. Hlavní důvodem výběru MongoDB je skutečnost, že se jedná o nejpoužívanější NoSQL databázi. AJAX – Aplikace bude plně AJAXová (takové aplikace bývají označovány jako single-page). Realizaci AJAXové aplikace výrazně usnadní použití frameworku AngularJS. Bezpečnost – RESTful API bude zabezpečeno pomocí metody Basic access authentication. Uživatel, který bude chtít využívat API, bude muset být přihlášen ve webovém rozhraní, nebo bude muset zasílat v požadavku autentizační informace. Ty budou pro každého uživatele unikátní. Výkon – Analýza stránky by neměla trvat déle než 10 vteřin. Uživatel by měl mít možnost zjistit, jak dlouho již analyzování probíhá. Uživatelské rozhraní – Layout aplikace bude responsivní. Vzhledem k informačnímu charakteru navrhované webové aplikace přispěje responsivní layout k efektivnímu využití jinak volného prostoru na displejích s různým rozlišením. 46
4.2. Návrh uživatelského rozhraní
Obrázek 4.1: Prototyp uživatelského rozhranní
4.2
Návrh uživatelského rozhraní
Při návrhu uživatelského rozhraní je nutné klást důraz na uživatelskou přívětivost. Jakákoliv webová stránka či aplikace by měla být přístupná a použitelná. V následujících řádcích proto stručně shrnu jednotlivé oblasti, které jsem zohlednil při vytváření prototypu aplikace. Prototyp uživatelského rozhraní znázorňuje Obrázek 4.1. Vytvořen byl programem Justinmind Prototyper47 . Layout a rozměry stránky – Layout je rozmístění základních prvků na stránce. Je to tedy jakési schéma, které říká, kde bude umístěn logotyp, hlavní navigace, drobečková navigace, formulář pro fulltextové vyhledávání a další obvyklé součásti stránky. Dobrý layout je základem 47
http://www.justinmind.com
47
4. Analýza a návrh použitelnosti každé webové prezentace. Nedoporučuje se hýbat s prvky, u kterých jsou uživatelé zvyklí na jejich přibližné umístění. Členění a srozumitelnost textu – Členění textu a jeho přívětivost k porozumění by měla být vždy základním pilířem každého webu, jelikož cílem bývá většinou prezentovat právě obsah. V roce 1997 vydal Jakob Nielsen zajímavou studii, jejímž závěrem bylo, že zkrácením, rozčleněním a zneutralizováním textu se může použitelnost obsahu zvýšit i o více než 100 procent. [35] Aplikace tak bude výsledky testu představovat maximálně stručně a přehledně, s využitím četných tabulek a záložek. Navigace – Navigace by měla být konzistentní a od okolního obsahu vizuálně oddělena. Uživatelé by měli mít možnost přejít snadno v hierarchii webu o úroveň výše, stejně jako na úvodní stránku. V navrhované aplikaci bude navigace zobrazena, i když ji zrovna nepůjde používat, v takovém případě bude ale téměř transparentní. Nepřetržité zobrazení navigace usnadní orientaci v uživatelském rozhraní. Prvky uživatelského rozhraní – Uživatelské rozhraní by mělo být na všech podstránkách stejné. Vyskakování nových oken a jakékoliv změny obsahu bez přičinění uživatele jsou nepřijatelné. [55] Tisk – Četná testování potvrdila, že mnozí uživatelé buďto neumí tisknout z prohlížeče, nebo to umí, ale bojí se, že se jim stránka vytiskne tak, jak ji vidí v prohlížeči (neumějí si zobrazit tiskový náhled). Tento problém často řeší překopírováním obsahu do textového editoru a tisknutím z něj. Uživatelům bychom měli proto nabídnout tlačítko pro tisk, v horším případě se alespoň přesvědčit, že text ve stránce lze snadno kopírovat. [46] Z těchto důvodů bude aplikace obsahovat tlačítko pro zobrazení tiskové verze.
4.3
Návrh architektury systému
Aplikace poběží na platformě Node.js a bude nasazená na Heroku. Data budou uložena v databázi MongoDB, kterou poskytne MongoLab. Uživatel bude aplikaci využívat prostřednictvím svého prohlížeče. Komunikaci s RESTful API obstará AngularJS prostřednictvím AJAXu. Diagram nasazení zobrazuje Obrázek 4.2.
4.3.1
Databázové schéma
Komunikaci s databází zajistí modul Mongoose. MongoDB je bezschémová databáze, přesto je při použití modulu Mongoose nutné definovat schéma kolekce. Tím je zajištěno, že se do databáze nedostanou nevalidní data. 48
4.3. Návrh architektury systému
Obrázek 4.2: Diagram nasazení
Schéma je jednoduše rozšiřitelné pomocí pluginů – namísto použití předdefinovaných datových typů (String, Number, Date, Buffer, Boolean, Mixed, ObjectId, Array) si tak můžeme vytvořit typ vlastní. Nebo můžeme využít datový typ, který již vytvořil někdo jiný.48 Aplikace bude obsahovat dvě kolekce: User a Test. Kolekce Test bude obsahovat zejména URL analyzované stránky, výsledky analýzy a referenci na uživatele, který je vlastníkem daného testu: var testFields = { user: { type: url: { type: image: { type: created: { type: results: { } }
Schema.ObjectId, ref: "User" }, String }, String }, Date, default: Date.now },
Kolekce User bude obsahovat jméno, e-mail, heslo, autentizační klíč pro využívání API a příznak, zda je účet uživatele aktivní: var userFields = { name: { type: email: { type: pass: { type: authKey: { type: active: { type: }
String }, String }, String }, String }, Boolean, default: false }
Vlastní autentizační klíč nalezne uživatel ve webovém rozhraní v Editaci profilu. Díky tomuto klíči bude moci využívat API pro manipulaci s testy. Autentizační klíč je dvojice _id a pass oddělená dvojtečkou a zakódovaná do Base64. Heslo v pass je hašované funkcí SHA-1. 48
http://plugins.mongoosejs.com
49
4. Analýza a návrh Tabulka 4.1: Popis RESTful webové služby Označení akce A1 A2 A3 A4 A5 A6
HTTP metoda GET POST DELETE GET PUT DELETE
Adresa /tests /tests /tests /tests/:test /tests/:test /tests/:test
Popis historie testů vytvoření testu smazání testů detail testu editace testu smazání testu
Tabulka 4.2: Kontroly prováděné v rámci RESTful webové služby Typ kontroly Existence testu Požadovaný formát odpovědi Autentizace Autorizace Formát požadavku Validita dat
4.3.2
A1 7 3 3 7 7 7
Označení akce A2 A3 A4 A5 7 7 3 3 3 3 3 3 3 3 3 3 7 7 3 3 3 7 7 3 3 7 7 3
A6 3 3 3 3 7 7
Vytvoření testu
Uživatel má možnost uskutečnit analýzu webové stránky (dále jen test) prostřednictvím uživatelského rozhraní či přímo pomocí RESTful API. Strukturu API pro manipulaci s testy zachycuje Tabulka 4.1. Před provedením konkrétní akce je nejprve nutné provést řadu kontrol: Existence daného testu – Pokud chce uživatel přistoupit k testu, který neexistuje, obdrží návratový kód 404 Not Found. Požadovaný formát odpovědi – Pokud uživatel zaslal požadovaný formát odpovědi v hlavičce požadavku (v parametru Accept) a nejedná se o formát application/json, obdrží návratový kód 406 Not Acceptable. Autentizace – Pokud uživatel není přihlášen pomocí session nebo nezaslal správné autentizační informace v hlavičce požadavku (v parametru Authorization), obdrží návratový kód 401 Unauthorized. Autorizace – Pokud je uživatel autentizován a přistupuje k testu, jehož není vlastníkem, obdrží návratový kód 403 Forbidden. Formát požadavku – Pokud je formát požadavku v hlavičce uveden (parametrem Content-Type) a nejedná se o application/json, obdrží uživatel návratový kód 415 Unsupported Media Type. 50
4.3. Návrh architektury systému Validita dat v požadavku – Pokud data zaslaná v těle požadavku nejsou validní, obdrží uživatel návratový kód 400 Bad Request. Kontroly probíhají v uvedeném pořadí, nejsou ale prováděny nutně všechny. Například při zobrazení testu není kontrolován formát dat v požadavku, protože se žádná data neodesílají. Naproti tomu je kontrolována autorizace, protože uživatel, který požaduje zobrazení testu, musí být zároveň jeho vlastníkem. U vytváření testu je tomu naopak – formát dat je kontrolován a autorizace kontrolována není. Stačí, když bude uživatel autentizován. Tabulka 4.2 ukazuje, jaké kontroly jsou v případě konkrétních akcí vykonávány. Průběh zobrazení testu je zachycen diagramem aktivit na Obrázku 4.3. Průběh vytvoření testu zobrazuje diagram aktivit na Obrázku 4.4.
Obrázek 4.3: Diagram aktivit – zobrazení testu
51
4. Analýza a návrh
Obrázek 4.4: Diagram aktivit – vytvoření testu
Z obou diagramů aktivit je patrné, že autentizace uživatele je možná dvojím způsobem – buďto pomocí session, nebo pomocí Basic access authentication. Nejprve je zkontrolováno přihlášení pomocí session. Pokud uživatel není přihlášen, kontroluje se, zda zaslal autentizační informace v hlavičce požadavku: GET /api/tests HTTP/1.1 Host: localhost:5000 Authorization: Basic NTE3Zjk2YjU3M2NjNzlkMDBmMDAwMDA4OjI1MD= Webová aplikace poběží na frameworku AngularJS, který využívá pro přístup k testům navržené API. Protože AngularJS se nachází na straně klienta, 52
4.3. Návrh architektury systému
Obrázek 4.5: Sekvenční diagram – vytvoření testu
není možné využívat Basic access authentication. Do JavaScriptových souborů nemůžeme dát „napevno“ autentizační informace, která se mají posílat v požadavku, protože by si je kdokoliv mohl zobrazit, a navíc stejně musí být pro každého uživatele unikátní. Na druhou stranu s autentizací pouze přes session bychom si také nevystačili, protože API je veřejná webová služba a není nutné ji využívat výhradně skrze AngularJS. Proto je možné se autentizovat pomocí session, stejně jako prostřednictvím Basic access authentication. Autentizace přes session bude uplatňována přednostně, a proto dotazy na API, které povedou z AngularJS, budou vykonány, i když nebudou v hlavičce obsahovat autentizační údaje. Obrázek 4.5 zobrazuje sekvenční diagram vytvoření testu. Sekvenční diagram zobrazuje situaci, kdy uživatel je již autentizován a nic nebrání provedení analýzy webové stránky – všechny požadované podmínky jsou splněny. Uživatel vytváří test prostřednictvím webové aplikace. Odeslání formuláře s URL adresou odchytí AngularJS prostřednictvím direktivy ngSubmit. Controller v AngularJS, který má řídící funkci nad danou stránkou, zavolá metodu save(), která odešle požadavek metodou POST na RESTful API. Controller na serveru, který má na starosti zpracování daného požadavku, nejprve ověří, že 53
4. Analýza a návrh odeslaná URL adresa je dostupná. Jako dostupná URL je považována adresa, která vrací odpověď se stavovým kódem 200, 301 nebo 302. Poté se provedou volání na API různých služeb, která poskytnou informace o testované webové stránce. Důležité je, aby tato volání byla asynchronní a tedy neblokující. Paralelně je tak možné získat informace třeba z deseti zdrojů a po obdržení informací z posledního zdroje výsledky uložit do databáze a v odpovědi vrátit uživateli. Jakmile AngularJS obdrží odpověď od RESTful webové služby, překreslí obsah šablony a provede změnu URL fragmentu. Uživatel tím pádem pravděpodobně ani nepozná, že webová aplikace je AJAXová.
54
Kapitola
Implementace Aplikace je navržená podle architektonického stylu MVC. Základ aplikace tvoří framework Express49 a modul Express Resource50 , který usnadňuje vytvoření RESTful API. Komunikaci s databází obstarává modul Mongoose51 . Dynamické view je postaveno na frameworku AngularJS.
5.1
Konfigurace
V souboru init.js nastavuji konfiguraci aplikace. Funkce configure(), která neobsahuje v 1. parametru název prostředí, je společná pro všechna prostředí (production, test i development). Jedná se tedy o výchozí konfiguraci. Funkce configure() s definicí prostředí upravuje připojení do databáze. Ve výchozí konfiguraci využívám několik middlewarů. Pod pojmem middleware se v kontextu Expressu rozumí funkce, která přijme objekt požadavku a odpovědi, provede nějakou akci a nakonec zavolá funkci next(), která přesune zpracování požadavku na další middleware. V aplikaci jsem využil: cookieParser – Naplní objekt req.cookies podle informací z parametru Cookie v hlavičce požadavku. Použití tohoto middlewaru je nutné pro potřeby middlewaru connect-flash. bodyParser – Poskytne objekt req.body obsahující tělo požadavku. Tento middleware představuje wrapper middlewarů multipart, urlencoded a json. static – Poskytne statický přístup k souborům v uvedeném adresáři. Tyto soubory nebudou aplikací nijak zpracovány. 49
https://github.com/visionmedia/express https://github.com/visionmedia/express-resource 51 http://mongoosejs.com 50
55
5
5. Implementace session – Přidá podporu pro session. Tento middleware musí být použit před inicializací modulu Passport, který využívám pro autentizaci uživatele. connect-flash – Přidá podporu pro req.flash(). Tato funkcionalita umožní používat „Flash Messages“ – krátké informační zprávy, které upozorní v šabloně uživatele na výsledky určité akce ( „produkt byl úšpěšně smazán“, „operace se nezdařila“ apod.). Flash Messages byly součástí frameworku Connect, ve frameworku Express ale nejsou nativně podporovány. router – Provede routy definované v souboru routes.js. passport – Modul Passport52 patří spolu s modulem Everyauth k nejoblíbenějším autentizačním middlewarům v Node.js. Obsahuje více než 120 autentizačních strategií, které se instalují zvlášť. V práci jsem využil strategii passport-local53 . error – Zajistí zpracování chyb. Middleware pro zpracování chyb je vždy funkce se 4 argumenty (err, req, res, next). Je možné použít více middlewarů, a reagovat tak rozdílně na různé typu požadavku. Má definice vypisuje chybu v šabloně error.html: function(err, req, res, next){ var status = err.status || 500, message = err.message || "Vyskytla se chyba"; res.status(status); return res.render("error", { status: status, title: message, url: "http://" + req.headers.host + req.url }); }
5.2
Model
Datový model aplikace reprezentuje adresář models. Zde najdeme soubor Test.js, který představuje model pro testy, a soubor User.js, který je modelem pro uživatele. Schéma pro kolekci Test již bylo částečně popsáno v Kapitole 4.3.1. Ve výsledné implementaci v něm přibyly další položky (viz Výpis kódu 5.1). 52 53
56
http://passportjs.org https://github.com/jaredhanson/passport-local
5.2. Model Výpis kódu 5.1: Schéma pro kolekci Test 1 2 3 4 5 6 7 8 9 10 11
var testFields = { user: { type: url: { type: image: { type: hostName: { type: basicUrl: { type: word1: { type: word2: { type: created: { type: results: { } }
Schema . ObjectId , ref: " User " } , String } , String } , String } , String , default: " " } , String , default: " " } , String , default: " " } , Date , default: Date . now } ,
Ve schématu Test definuji dvě statické metody: load() a inSchema(). Metoda load() simuluje operaci JOIN, protože naplní položku Test.user odpovídajícími daty z kolekce User. Metoda inSchema() dostává jako parametr seznam položek, které chce uživatel v testu editovat. Úlohou metody je zkontrolovat, zda se všechny položky nachází ve schématu. Pokud ne, vrátí metoda false a uživatel obdrží návratový kód 400 Bad Request. Obě metody zachycuje Výpis kódu 5.2. Výpis kódu 5.2: Schéma Test – statické metody 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
TestSchema . statics = { load: function ( id , cb ) { return this . findById ( id ) . populate ( " user " , " name email pass " ) . exec ( cb ) ; }, inSchema: function ( arr ) { var select = arr . split ( " ," ) ; for ( var i = 0; i < select . length ; i ++) { var field = select [ i ]. replace (/^\ s +|\ s +$/ g , " " ) ; if (( field != " _id " ) && ( field != " __v " ) ) { if ( typeof fields [ field ] === " undefined " ) { return false ; } } } return true ; } }
Ve schématu User definuji několik instančních metod a jednu metodu statickou. Instanční metody souvisí s autentizací uživatele. Statická metoda inDB() je obalem nad nativní metodou findOne(), která vybírá dokument z kolekce na základě stanovené podmínky. Podmínkou je v tomto případě shoda v e-mailu. Pokud se nepodaří nalézt v kolekci žádného uživatele, volá se callback s prvním parametrem typu Error. Pokud shoda nastane, volá se callback s prvním parametrem null. Toto je základní princip volání callbacků v Node.js. 57
5. Implementace Výpis kódu 5.3: Schéma User – instanční a statické metody 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
UserSchema . methods = { authenticate: function ( plainText ) { return this . encryptPass ( plainText ) === this . pass ; }, makeSalt: function () { return Math . round (( new Date () . valueOf () * Math . random () ) ) ; }, encryptPass: function ( pass ) { if (! pass ) return " " ; return crypto . createHmac ( " sha1 " , this . salt ) . update ( pass ) . digest ( " hex " ) ; } }; UserSchema . statics . inDB = function ( email , cb ) { return this . findOne ({ email: email } , function ( err , user ) { if (! user ) return cb ( null , user ) ; cb ( new Error ( " Uzivatel jiz existuje " ) , user ) ; }) ; };
5.3
Controller
Controllery se nachází v adresáři controllers – soubor testController.js definuje RESTful API pro manipulaci s testy, userController.js představuje controller pro uživatele a renderController.js je zodpovědný za vyrenderování šablony. API pro testy umožňuje provádět 6 akcí, API pro uživatele pouze 3 akce. Data jsou vždy vrácena ve formátu JSON. Jednotlivé akce jsou obslouženy metodami objektu resource, který pochází z modulu Express Resource. API, jehož strukturu zachycuje Tabulka 5.1 a 5.2, je využíváno službou $resource v AngularJS. API pro manipulaci s uživateli není veřejné – je vytvořeno pouze pro volání z AngularJS, takže autentizace a autorizace je prováděna výhradně přes session. API definuje pouze 3 akce, protože některé akce, jako registrace, resetování hesla či přihlášení, jeho prostřednictvím řešeny nejsou. Je to z toho důvodu, že ne všechny šablony jsou napojeny na AngularJS.
5.3.1
TestController
Stěžejním a nejkomplexnějším procesem je vytvoření testu. Podmínky, které je nutné splnit, aby vytvoření testu skončilo úspěšně, byly popsány v Kapitole 4.3.2. V následující části bude proto popsán samotný postup sběru dat. Pro získávání informací o webové stránce z externích zdrojů jsem se snažil využívat co nejvíce dostupná API. Protože ne všechny zdroje API nabízejí, nevyhnul jsem se využití web scrapingu. 58
5.3. Controller Tabulka 5.1: Popis RESTful webové služby Metoda GET POST DELETE GET PUT DELETE
Adresa /tests /tests /tests /tests/:test /tests/:test /tests/:test
Obsluh. metoda index() create() destroyAll() show() update() destroy()
Popis historie testů vytvoření testu smazání testů detail testu editace testu smazání testu
Tabulka 5.2: Popis API pro AngularJS Metoda GET PUT DELETE
Adresa /profile/:profil /profile/:profil /profile/:profil
Obsluh. metoda show() update() destroy()
Popis detail uživatele editace uživatele smazání uživatele
Informace z jednotlivých zdrojů jsou získávány paralelně. Pro zjednodušení celého zápisu jsem využil modul Async54 – pravděpodobně nejpoužívanější modul pro kontrolu běhu asynchronních operací. Prvním argumentem funkce parallel() je množina metod, které se mají asynchronně provést. Každá metoda z této množiny po skončení volá callback(), který přijímá v parametru. Jakmile všechny metody zavolají svůj callback, provede se „finální“ callback, který je druhým argumentem funkce parallel(). Zjednodušený příklad použití modulu Async zobrazuje Výpis kódu 5.4. Výpis kódu 5.4: Použití modulu Async 1 2 3 4 5 6 7 8 9 10 11 12
async . parallel ([ function ( callback ) { // 1. uloha db . save ( " abeceda " , " A " , function ( err ) { callback () ; }) ; }, function ( callback ) { // 2. uloha db . save ( " abeceda " , " B " , function ( err ) { callback () ; }) ; } ] , function ( err ) { // finalni callback }) ;
Při analyzování webové stránky získávám informace od 13 zdrojů (viz Tabulka 5.3). Zdrojem se v tomto případě rozumí i webová stránka, pro kterou je analýza prováděna. Získávání informací z jednotlivých zdrojů je definováno v lib/services. 54
https://github.com/caolan/async
59
5. Implementace Tabulka 5.3: Zdroje pro získávání informací o stránce # 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13.
Zdroj Facebook Twitter Google Plus Alexa Rank PageRank S-rank Google Seznam Majestic SEO PageSpeed Insights Whois W3C Testovaná URL
Způsob získávání dat API API (neoficiální) web scraping API (neoficiální) API (neoficiální) API (neoficiální) web scraping web scraping web scraping API web scraping API web scraping
Facebook – Facebook poskytuje ke svým sociálním statistikám API, takže získání informací o počtu „lajků“, sdílení a komentářů k libovolné stránce je jednoduché. Obdržená data jsou ve formátu JSON. Twitter – Získání informace o počtu tweetů je možné neoficiální cestou dotazem na adresu http://urls.api.twitter.com/1/urls/count.json? url=URI. Obdržená data jsou ve formátu JSON. Google Plus – Google neposkytuje žádné API pro získání celkového počtu +1 k zadané URL adrese, přesto existuje způsob, jak tuto informaci získat. Stránku s tlačítkem +1 k libovolné adrese obdržíme na https:// plusone.google.com/u/0/_/%2B1/fastbutton?count=true&url=URI. Informaci o počtu hodnocení +1 pak lze vyparsovat z elementu s ID #aggregateCount. Pro vyparsování této informace jsem použil modul Cheerio55 , který umožňuje vytvořit DOM a pracovat s ním (výběr, manipulace, procházení) na způsob knihovny jQuery. Ve skutečnosti jQuery ale nepoužívá. Alternativou k Cheerio je modul jsdom, který je ovšem pomalejší a složitější na implementaci. Alexa Rank – Informaci o dosaženém globálním a lokálním Alexa Ranku lze získat z XML, které obdržíme voláním adresy http://data.alexa. com/data?cli=10&dat=s&url=URL. Protože Cheerio umožňuje parsovat nejen HTML, ale i XML, je jeho použití možné i v tomto případě. PageRank – Informaci o dosaženém PageRanku lze získat prostřednictvím již existujícího modulu node-pagerank56 . 55 56
60
https://github.com/MatthewMueller/cheerio https://github.com/nfriedly/node-pagerank
5.3. Controller S-rank – Seznam neuvádí dokumentaci k žádnému API a zájemce o zjištění S-ranku proto odkazuje na stažení Seznam Lištičky – nástrojové lišty určené pro prohlížeče Internet Explorer, Firefox a Chrome. Informaci o dosaženém ranku lze přesto zjistit prostřednictvím XML-RPC požadavku na adresu http://srank.seznam.cz. Pro tyto účely jsem využil modul node-xmlrpc57 . Google, Seznam – Ze SERP Googlu a Seznamu ukládám do databáze prvních deset výsledků a informaci o celkovém počtu zaindexovaných stran. Výsledky vyhledávání Seznamu se od Googlu v zásadě nijak neliší, pouze Seznam navíc poskytuje ke každému výsledku náhledový obrázek. K parsování byl použit modul Cheerio. Whois – Registr Whois poskytuje informace o datu zaregistrování domény. Datum zaregistrování se může v registru zobrazovat na rozličných místech a v různých podobách – implementoval jsem proto 3 způsoby, jak datum ze stránek vyparsovat. K parsování jsem použil modul Cheerio. Majestic SEO – Z webu Majestic SEO získávám web scrapingem informace o počtu zpětných odkazů. I zde jsem použil k parsování modul Cheerio. PageSpeed Insights – Google poskytuje pro využívání služby PageSpeed Insights bezplatné API s denním limitem 2 500 volání. Před použitím je proto nutné vygenerovat soukromý klíč, který je jedním z parametrů v dotazu na API. Volitelným parametrem je také IP adresa. Jejím uvedením lze zabránit neúměrnému volání z jednoho zařízení. Obdržená data jsou ve formátu JSON. W3C – Validátor od W3C sice poskytuje API, ale služba jako taková se jevila poměrně nestabilní. Protože měla mnohdy velmi pomalou odezvu, rozhodl jsem se validátor umístit na vlastní virtuální server. Namísto adresy http://validator.w3.org/check?uri=URI proto v aplikaci volám http://31.31.75.40/w3c-validator/check?uri=URI. Data jsou vrácena ve formátu JSON. Testovaná stránka – Informace ze stránky získávám asynchronně s použitím modulu Async. Parsování dat provádím modulem Cheerio. Abych určil, jaká je skutečná hustota nejčastějších slov, je třeba odstranit z textu všechna stop slova. Získal jsem stop slova pro 13 jazyků.58 Protože jsou bez diakritiky, musím nejdříve odstranit z výchozího textu diakritiku, poté vyfiltrovat stop slova a nakonec zbývajícím slovům v textu diakritiku vrátit. 57 58
https://github.com/baalexander/node-xmlrpc http://www.ranks.nl/resources/stopwords.html
61
5. Implementace Součástí testu je i kontrola dostupnosti odkazů, které se na stránce vyskytují. Ke každému testovanému odkazu ukládám do databáze informace o odezvě a návratovém kódu. Testuji však maximálně 50 unikátních odkazů. Pro účely testování odkazů je zapotřebí navýšit hodnotu proměnné maxSockets, která je defaultně nastavena na 5. Tato proměnná vyjadřuje, kolik může mít HTTP agent souběžně otevřených soketů na jednoho hostitele. Také testuji návratový kód adresy /sitemap.xml. Pokud je návratový kód 200 nebo 302, mapa stránek určitě existuje. V opačném případě je možné (nikoliv jisté), že mapa stránek neexistuje. Jedním z požadavků na aplikaci je vytvoření screenshotu testované stránky. K tomuto účelu jsem využil modul Phantom59 , který umožňuje pohodlně využívat WebKit PhantomJS60 v Node.js. Aby bylo možné tento WebKit použít, je třeba mít definovanou cestu k programu v systémové proměnné PATH. Modul Phantom vyžaduje pro bezproblémový běh Node.js ve verzi 0.8.1. Na novějších verzích jsem se potýkal s problémy. Bohužel se mi nepodařilo zprovoznit PhantomJS na hostingu Heroku. Z tohoto důvodu doporučuji v produkčním prostředí použít Node.js ve verzi 0.10.4 (screenshoty se prozatím tvořit nebudou) a ve vývojovém prostředí Node.js ve verzi 0.8.1 (zde nic nebrání PhantomJS používat). Do budoucna zvážím změnu hostingu, případně se ještě pokusím najít způsob, jak na Heroku tvorbu screenshotů zprovoznit. V případě úspěšného vytvoření testu obdrží uživatel v hlavičce odpovědi parametr Location a v těle odpovědi data k nově vzniklému testu. Návratový kód obdrží 201 Created. Na stránce s historií testů je u každého testu vypsáno pouze pár základních informací, proto je nutné vyfiltrovat z databáze pouze relevantní položky. Report z každého testu je velmi rozsáhlý a rozdíl v datové náročnosti dotazu s filtrováním a bez filtrování tak může představovat i jednotky MB. Výpis testů je doplněn stránkováním, takže kolekce není odesílána celá (viz Výpis kódu 5.5). Výpis kódu 5.5: Historie testů 1 2 3
var skip = req . query . offset || 0 , limit = req . query . limit || " " , sl = req . query . select || " " ;
4 5 6 7
if ( sl ) { if (! Test . inSchema ( sl ) ) return next ( new error . BadRequest () ) ; } 59 60
62
https://github.com/sgentle/phantomjs-node http://phantomjs.org
5.3. Controller
8 9 10 11 12 13
Test . find ({}) . select ( sel ) . sort ( " - created " ) . skip ( skip ) . limit ( limit ) . exec ( function ( err , docs ) { if ( err ) return next ( err ) ; res . setHeader ( " Content - Type " , " application / json " ) ; res . send ( docs ) ; }) ;
Při přístupu ke konkrétnímu testu se provádí kontrola, zda požadovaný test existuje. Kontrola existence testu je obsažena v metodě load(), což je metoda objektu resource umožňující auto-loading. Auto-loading znamená, že po zavolání callbacku se objekt req.test automaticky naplní asociovanými daty. Tato metoda je využita nejen při zobrazení testu, ale i při jeho editaci či mazání.
5.3.2
UserController
UserController.js obsahuje metody pro provedení těchto akcí: • registrace/aktivace účtu, • vygenerování a zaslání zapomenutého hesla, • přihlášení/odhlášení, • zobrazení profilu, • editace profilu, • smazání účtu. Uživatel, který chce využívat aplikaci, musí být zaregistrován. Po vytvoření registrace je na jeho e-mail zaslán aktivační odkaz ve tvaru /activate/USER_ID. USER_ID představuje hash 24 znaků, takže není možné jej uhodnout. K odesílání e-mailů jsem použil modul Nodemailer61 . Pokud se uživatel rozhodne, že chce nenávratně smazat svůj účet, dojde ke smazání i všech testů, které provedl. Oba požadavky, smazání účtu i smazání korespondujících testů, zavolá přitom AngularJS prostřednictvím API (viz Výpis kódu 5.6). V aplikaci tak nejsou metody pro tyto akce v žádné vazbě. Výpis kódu 5.6: Smazání účtu uživatele v AngularJS 1 2 3 4 5 6
$ scope . remove = function () { $ location . path ( " / " ) ; Test . removeAll () ; // smaze testy User . remove ({ user: $ routeParams . user }) ; // smaze uziv . ucet window . location . href = $ location . absUrl () + " login ? del " ; };
61
https://github.com/andris9/Nodemailer
63
5. Implementace
5.4
View
Šablona je postavená na CSS frameworku Bootstrap. Aby aplikace získala působivější vzhled, využil jsem komerční šablonu Blue Moon62 , kterou jsem pro účely aplikace pouze patřičně upravil. V adresáři layouts se nachází celkem 5 šablon: • error.html – šablona určená k vypsání informace o chybě (např. 404), • signup.html – šablona pro registraci uživatele, • login.html – šablona pro přihlášení uživatele, • reset.html – šablona pro zaslání zapomenutého hesla, • layout.html – standardní šablona, která se používá po přihlášení. Všechny šablony využívají jednoduchý šablonovací systém EJS63 (Embedded JavaScript). Díky němu mohu ve stránce zobrazit obsah přiřazené proměnné – např. informační hlášku o úspěchu či neúspěchu určité akce (Flash message). Šablony error.html, signup.html, login.html ani reset.html nejsou napojeny na AngularJS. Jediná šablona, která je napojená na AngularJS, je layout.html. Tato šablona se používá po celou dobu, kdy je uživatel přihlášen. Věškeré akce po přihlášení jsou tudíž AJAXové a využívají navržené RESTful API. Zpracování šablony layout.html frameworkem AngularJS zajišťuje direktiva ng-app na elementu html. Pomocí direktivy ng-switch pro změnu určím, zda se má konkrétní stránka zobrazit v jednosloupcovém či dvousloupcovém rozložení. Důvod, proč nelze oddělit tato dvě rozložení do samostatných souborů, např. layoutOneColumn.html a layoutTwoColumns.html, spočívá v AJAXovém běhu aplikace. Načtení konkrétní šablony se provede při reloadu stránky (např. při stisknutí F5 v prohlížeči). V tomto okamžiku vykoná middleware Expressu routy definované v souboru routes.js. Jakmile se poté přihlášený uživatel pohybuje v uživatelském rozhraní, mění se vždy pouze konkrétní část rozhraní a o routování se stará výhradně AngularJS. Routování poskytuje služba $routeProvider (viz Výpisu kódu 5.7). Aby se URL v adresním řádku měnila způsobem, na který jsou uživatelé zvyklí u neAJAXových aplikací, využívám službu $locationProvider (viz Výpis kódu 5.8). Ta umožňuje povolit HTML5 mód a využívat tak možností HTML5 History API. Bez povoleného HTML5 módu by URL adresy měly podobu: http://domena.cz/#!/slug. Takováto adresa bývá označována termínem Hashbang URL. 62 63
64
http://iamsrinu.com/bluemoon-admin-theme/ https://github.com/visionmedia/ejs
5.4. View Výpis kódu 5.7: Služba $routeProvider 1 2 3 4 5 6 7 8 9 10
module . config ( function routes ($ routeProvider ) { $ routeProvider . when ( ’/ ’ , { templateUrl: ’/ views / index . html ’ , controller: ’ IndexController ’ }) ; $ routeProvider . when ( ’/ tests ’ , { templateUrl: ’/ views / test_list . html ’ , controller: ’ TestsController ’ }) ; ... $ routeProvider . otherwise ({ redirectTo: ’/ ’ }) ; }) ;
Výpis kódu 5.8: Služba $locationProvider 1 2 3
module . config ( function url ($ locationProvider ) { $ locationProvider . html5Mode ( true ) ; }) ;
Zobrazení jednotlivých typů stránek zajišťují soubory v public/views. Obsah konkrétního souboru se aplikuje v místě direktivy ng-view. Kromě této direktivy využívám dalších cca 15 nativních direktiv a nespočet direktiv převzatých. Veškerou logiku dynamického View lze nalézt v public/app. Krom direktiv jsou zde definovány také služby, filtry a controllery. Využité knihovny se nachází v public/lib.
5.4.1
Komunikace s RESTful API
Angular komunikuje s RESTful API prostřednictvím služby $resource. Tento objekt již v základu obsahuje několik přednastavených metod: get/(GET), save (POST), query (GET/isArray), remove (DELETE) a delete (DELETE). Metody delete() a remove() se od sebe nijak neliší, jedná se o aliasy. Službě $resource tedy chybí akce pro PUT a DELETE/isArray, které je jako jediné nutné definovat (viz Výpis kódu 5.9). Výpis kódu 5.9: Rozšíření $resource pro komunikaci s API 1 2 3 4 5 6
module . factory ( " Test " , function ($ resource ) { return $ resource ( " / api / tests / :test " , {} , { update: { method: " PUT " } , removeAll: { method: " DELETE " , isArray: true } }) ; }) ;
7 8 9 10 11 12
module . factory ( " User " , function ($ resource ) { return $ resource ( " / api / profiles / :user " , {} , { update: { method: " PUT " } }) ; }) ;
65
Kapitola
Testování 6.1
Jednotkové testování
Jednotkové (unit) testy představují testování na nejnižší možné úrovni. Testuje se izolovaná část kódu, která (v ideálním případě) není závislá na žádném kódu mimo testovanou jednotku. Případné závislosti se nahrazují falešnými objekty, které se označují jako mocks (nebo také stubs či fakes) a jejichž jedinou úlohou je požadované chování simulovat. Díky tomu jsou jednotkové testy velmi rychlé, a měly by proto být spouštěny při každé změně kódu.
6.1.1
Mocha
Pro jednotkové a integrační testování jsem zvolil testovací framework Mocha, jehož autorem je TJ Holowaychuk. Jednotkové testy se nachází v adresáři test/server/unit. Struktura testů je tvořena dvěma funkcemi – funkcí describe(), která sdružuje související testy, a funkcí it() obalující jeden konkrétní test. Nastavení prostředí pro testování je následující: • V souboru package.json specifikuji v sekci scripts, že se testy spustí příkazem npm test. Testy se provedou na všech souborech v adresáři test/server. Pokud by cesta k adresáři nebyla uvedena, provedly by se automaticky na adresáři test. • V souboru init.js je specifikována sekce test, kde nastavuji připojení do testovací databáze. Díky tomu je možné v rámci testů databázi libovolně mazat/plnit bez obav ze ztráty produkčních dat. • V souboru mocha.opts je definováno, že se před spuštěním testů má nejdříve načíst soubor mocha.js – zde nastavuji prostředí běhu testů na test. Dále načítám modul Should.js pro asserty, jako reporter vybírám dot, nastavuji styl testování na BDD (behaviour-driven development) a 67
6
6. Testování povoluji rekurzivní procházení testovaného adresáře. Reporter dot (resp. Dot Matrix) je ze všech reporterů nejjednodušší – vykreslí pro každý test různě barevnou tečku: chybný test má červenou, pomalý test žlutou a probíhající test modrou barvu. Výpis kódu 6.1: Nastavení frameworku Mocha v souboru mocha.opts -- require ./ test / mocha . js -- require should -- reporter dot -- ui bdd -- recursive
1 2 3 4 5
6.1.2
Should.js
Pro asserty jsem použil modul Should.js64 , který opět vytvořil TJ Holowaychuk. Should.js je nadstavba nad vestavěným modulem Assert. Rozšiřuje vlastnost prototype všech objektů tím, že k ním přidává objekt should, na kterém můžeme volat metody pro asserty. Výpis kódu 6.2: Příklady některých možných assertů s modulem Should.js 1 2 3 4 5 6 7 8 9 10
true . should . be . ok false . should . not . be . ok false . should . be . false []. should . be . empty (4) . should . equal (4) user . age . should . be . within (5 , 50) []. should . be . an . instanceOf ( Array ) ({ foo: " bar " }) . should . have . ownProperty ( " foo " ) res . should . be . json [1 ,2 ,3]. should . include (3)
6.1.3
Mocco
Pro tvorbu mock objektů jsem použil modul Mocco65 od Jakuba Mrozka. Mocco umožňuje použitím metody hijack() vytvořit falešnou implementaci libovolné metody určitého objektu. Po zavolání metody restore() můžeme obnovit všechny metody určitého objektu nebo případně i všechny metody všech objektů. Výpis kódu 6.3: Jednotkový test s použitím modulu Should.js a Mocco 1 2
var mocco = require ( " mocco " ) , Test = require ( process . cwd () + " / models / Test " ) ; 64 65
68
https://github.com/visionmedia/should.js https://github.com/JakubMrozek/mocco
6.2. Integrační testování
3 4 5 6 7 8 9 10 11 12 13
describe ( " model User " , function () { describe ( " metoda inDB " , function () { it ( " zavola metodu findOne () " , function () { mocco . mock ( User ) . hijack ( function findOne ( email ) { email . should . eql ({ email: " serakmat@fit . cvut . cz " }) ; }) ; User . inDB ( " serakmat@fit . cvut . cz " , function () {}) ; mocco . restore () ; }) ; }) ; }) ;
6.2
Integrační testování
Integrační testy slouží k ověření, že jednotlivé části aplikace spolu navzájem spolupracují. Oproti jednotkovým testům je možné používat externí zdroje, jako jsou databáze, souborový systém apod. Z tohoto důvodu jsou integrační testy oproti jednotkovým pomalejší. Integrační testy se nachází v adresáři test/server/integration. Pomocí těchto testů ověřuji správnou funkčnost navrženého API. Pro simulaci zpracování HTTP požadavku používám balíček Supertest66 . Výpis kódu 6.4: Otestování metody PUT integračním testem 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
describe ( " PUT / api / tests / :test " , function () { it ( " edituje test ( vrati 200) " , function ( done ) { request ( app ) . put ( " / api / tests / " + id1 ) . send ({ word1: " jine_slovo " }) . expect (200) . end ( function ( err , res ) { if ( err ) return done ( err ) ; Test . findOne ({ word1: " jine_slovo " } , function ( err , doc ) { if ( err ) return done ( err ) ; doc . word1 . should . equal ( " jine_slovo " ) ; done () ; }) ; }) ; }) ;
16 17 18 19 20 21 22 23
it ( " vrati 400 , pokud data nejsou validni " , function ( done ) { request ( app ) . put ( " / api / tests / " + id1 ) . send ({ " nonsense " : " nonsense " }) . expect (400 , done ) ; }) ; }) ;
66
https://github.com/visionmedia/supertest
69
6. Testování Výpis kódu 6.5: Spuštění jednotkových a integračních testů pod Windows 1 2 3 4 5
C: \ Users \ Serak \ WebstormProjects \ nodeseo > npm test > nodeseo@1 .0.0 test C: \ Users \ Serak \ WebstormProjects \ nodeseo > mocha test / server ............................................. 46 tests complete (2 seconds )
6.3
End-to-end testování
AngularJS obsahuje Scenario Test Runner, což je jednoduchá HTML stránka, která do elementu iframe načítá testovanou stránku aplikace a provádí nad ní sadu e2e testů. Scenario Test Runner se spouští přes prohlížeč, takže aby aplikace danou URL nezpracovávala, je třeba přidat do souboru init.js informaci o tom, že tato URL bude brána jako statická: app.use(express.static(process.cwd() + "/test/angular")); AngularJS používá pro testování framework Jasmine. Terminologie je podobná frameworku Mocha, který jsem použil pro integrační a jednotkové testování. Rozdíl mezi Jasmine a Mocha je zejména v tom, že Mocha nemá vestavěný modul pro asserty, je flexibilnější a má o něco menší základnu stoupenců mezi programátory. Ani o jednom frameworku nelze říct, že by byl lepší nebo horší. V souboru scenarios.js lze nalézt jednotlivé scénáře pro e2e testování. Konkrétní úloha scénáře může vypadat třeba takto: • přejdi na seznam dokumentů, • ověř, že URL obsahuje slug67 seznam-dokumentu, • ověř, že počet dokumentů na stránce je roven X, • klikni na tlačítko editovat u prvního dokumentu, • ověř, že hodnota určitého pole je rovna Y, • změň hodnotu z Y na Z a odešli formulář, • proveď reload stránky, • ověř, že hodnota určitého pole je rovna Z. Před provedením e2e testu naplním databázi třemi testovacími dokumenty. Test pak spustím zadáním adresy http://localhost:5000/e2e/runner.html do adresního řádku prohlížeče. Výsledky testů zobrazují Obrázky 6.1 a 6.2. 67
70
Jako slug se označuje koncová část URL, která je „SEO-friendly“.
6.3. End-to-end testování
Obrázek 6.1: Scenario Test Runner
71
6. Testování
Obrázek 6.2: Scenario Test Runner
72
Závěr Cílem této práce bylo vytvořit nástroj, který by zanalyzoval webovou stránku v co nejširším rozsahu. Rozsah prováděné analýzy nebyl předem stanoven, bylo proto na mně, abych určil, které metriky by měla analýza sledovat. Při výběru metrik bylo nejdůležitější zjistit, zda daná metrika hraje jistou úlohu při stanovení pozice webové stránky ve výsledcích vyhledávání. Nemělo by kupříkladu valný význam zkoumat, jak je stránka datově objemná, pokud by na to vyhledávače nebraly zřetel. Ačkoliv je problematika SEO v odborné literatuře široce zmapována, kvalitu a věrohodnost některých zdrojů bych se odvážil zpochybňovat. Jednoduchý recept na dosáhnutí první pozice ve výsledcích vyhledávání zkrátka neexistuje. Kdyby existoval, nečinila by tržní hodnota Googlu stovky miliard dolarů. Vyhledávač Google by jen stěží někdo používal. Jistá doporučení v oblasti optimalizace pro vyhledávače přesto existují. Tím nejzásadnějším je paradoxně optimalizovat pro uživatele. Uživatelé jsou ti, kteří na internetu vyhledávají. Nacházet přitom chtějí kvalitní stránky s výborným obsahem. A přesně to se jim vyhledavače snaží nabídnout. Výborný obsah nelze automatizovaně zkontrolovat. Je ovšem možné zkontrolovat technické zpracování stránek či poukázat na nedostatky v oblasti off-page faktorů. Právě na tyto dvě oblasti se vytvořená aplikace orientuje. Úkolem bylo také určit, jak vyhodnocená data prezentovat uživateli, aby se v nich orientoval a navíc jim rozuměl. Výsledky z analýzy jsem se proto snažil prezentovat co nejpřehledněji, s využitím četných tabulek, záložek, barevných zvýraznění a grafů. Aplikace nepředkládá uživateli jednoznačné řešení problému, na možný problém spíše upozorňuje. Protože je aplikace postavena na poměrně mladých technologiích, setkal jsem se v průběhu jejího vývoje častokrát s problémy, které souvisely s dosud nevyladěnými chybami. Zde vidím největší nevýhodu použití jakékoliv technologie, která za sebou nemá delší historii. Vzhledem k tomu, že v aplikaci využívám web scraping, je třeba dát v budoucnu pozor na možné změny v uspořádání webových stránek, ze kterých tímto způsobem čerpám informace. 73
Závěr Za největší přínos pro sebe považuji osvojení si nových technologií. Platformu Node.js, framework AngularJS ani databázi MongoDB jsem v minulosti nikdy nevyužil. Z počátku jsem si proto kladl otázku, zda je realizace tohoto typu aplikace na těchto technologiích vůbec možná. Dnes již mohu říci, že je tento výběr nejen možný, ale i velmi vhodný. Po domluvě se zadavatelem jsme se rozhodli uvolnit zdrojové kódy pod open-source licencí MIT. Možnost nahlédnout do zdrojového kódu bude největším přínosem pro komunitu kolem Node.js, která v poslední době dramaticky roste. Jakékoliv demo aplikace jsou podle ohlasů v různých článcích velmi vítány. V budoucnu je možné rozšířit aplikaci o další oblasti, které dosud nejsou vyhodnocovány. Aplikace je navržená tak, aby jakékoliv přidání nové funkcionality bylo jednoduché.
74
Literatura [1]
Adamčík, J.: Co byste měli vědět o JavaScriptu 3: variable hoisting. [online], listopad 2010, [cit. 25. 2. 2013]. Dostupné z: http://goo.gl/cXWP8
[2]
Brewer, E. A.: Towards Robust Distributed Systems. [online], červenec 2000, [cit. 13. 3. 2013]. Dostupné z: http://www.cs.berkeley.edu/ ~brewer/cs262b-2004/PODC-keynote.pdf
[3]
Bruckner, T.; Voříšek, J.; Buchalcevová, A.: Tvorba informačních systémů. Praha: Grada Publishing, a.s., 2012, ISBN 978-80-247-4153-6, 60 s.
[4]
Data Binding in Angular. [online], [cit. 17. 3. 2013]. Dostupné z: http: //docs.angularjs.org/guide/dev_guide.templates.databinding
[5]
Dependency Injection. [online], [cit. 2. 3. 2013]. Dostupné z: http:// docs.angularjs.org/guide/di
[6]
Enge, E.; Spencer, S.; Fishkin, R.; aj.: The Art of SEO. Sebastopol, CA, USA: O’Reilly Media, 2010, ISBN 978-80-247-4153-6, 49–53 s.
[7]
Fielding, T. R.: Architectural Styles and the Design of Network-based Software Architectures. Irvine: University of California, 2000, 76–86, 109 s.
[8]
Fielding, T. R.: REST APIs must be hypertext-driven. [online], říjen 2008, [cit. 1. 2. 2013]. Dostupné z: http://roy.gbiv.com/untangled/ 2008/rest-apis-must-be-hypertext-driven
[9]
Fishkin, R.: Personalization and SEO – Whiteboard Friday. [online], březen 2013, [cit. 3. 5. 2013]. Dostupné z: http://www.seomoz.org/blog/ personalization-and-seo-whiteboard-friday
[10] Geisendörfer, F.: Felix’s Node.js Convincing the boss guide. [online], březen 2011, [cit. 28. 2. 201]. Dostupné z: http://nodeguide.com/ convincing_the_boss.html 75
Literatura [11] Hanák, D.: Úvod do AngularJS. [online], srpen 2012, [cit. 27. 2. 2013]. Dostupné z: http://www.devbook.cz/ javascript-tutorial-uvod-do-angularjs [12] Hare, K. W.: A Comparison of SQL and NoSQL Databases. [online], květen 2011, [cit. 13. 1. 2013]. Dostupné z: http://metadata-standards. org/Document-library/Documents-by-number/WG2-N1501-N1550/ WG2_N1537_SQL_Standard_and_NoSQL_Databases%202011-05.pdf [13] Hawkes, R.: Foundation HTML5 Canvas: For Games and Entertainment. New York: Apress, 2011, ISBN 978-1-4302-3291-9, 1–21 s. [14] Hoff, T.: Drop ACID and Think About Data. [online], květen 2009, [cit. 1. 3. 2013]. Dostupné z: http://highscalability.com/blog/2009/5/ 5/drop-acid-and-think-about-data.html [15] Hurst, N.: Visual Guide to NoSQL Systems. [online], březen 2010, [cit. 2. 3. 2013]. Dostupné z: http://blog.nahurst.com/ visual-guide-to-nosql-systems [16] IaaS versus PaaS. [online], [cit. 11. 3. 2013]. Dostupné z: http://www.microsoft.com/austria/enterprise/article.aspx? Id=IaaS+PaaS+und+SaaS [17] Jones, D.: Flow Metrics will change the way you look at links. [online], březen 2012, [cit. 24. 4. 2013]. Dostupné z: http://blog.majesticseo. com/development/flow-metrics [18] Jones, D.: Fresh Index Approaches 200 Billion. [online], říjen 2012, [cit. 24. 4. 2013]. Dostupné z: http://blog.majesticseo.com/general/ fresh-index-approaches-200-billion [19] Jones, R.: An EGEE Comparative Study: Grids and Clouds - Evolution or Revolution. [online], červen 2008, [cit. 9. 12. 2012]. Dostupné z: https: //edms.cern.ch/document/925013 [20] Kadlec, J.: REST a webové služby v jazyce Java. Brno: Masarykova Univerzita, 2010, 26 s. [21] Keith, J.: HTML5 For Web Designers. New York: Jeffrey Zeldman, 2010, ISBN 978-0-9844425-0-8, 40-55 s. [22] Kosek, J.: Historie a vývoj HTML. [online], 2010, [cit. 3. 12. 2012]. Dostupné z: http://htmlguru.cz/uvod-historie.html [23] Kotačka, V.: Architektonické principy RESTu. [online], řijen 2012, [cit. 13. 12. 2012]. Dostupné z: http://www.sw-samuraj.cz/2012/10/ architektonicke-principy-restu.html 76
Literatura [24] Kristina Chodorow, M. D.: MongoDB: The Definitive Guide. Sebastopol, CA, USA: O’Reilly Media, 2010, ISBN 978-1-449-38156-1, 5–21 s. [25] Lawson, B.; Sharp, R.: Introducing HTML5. Berkeley, CA, USA: New Riders, 2011, ISBN 978-0-321-68729-6, 8–9 s. [26] Lith, A.; Mattson, J.: Investigating storage solutions for large data. [online], 2010, [cit. 18. 3. 2013]. Dostupné z: http://publications.lib. chalmers.se/records/fulltext/123839.pdf [27] Morrison, J.: HTML5 & CSS3 Support. [online], 2012, [cit. 15. 12. 2012]. Dostupné z: http://www.findmebyip.com/litmus [28] Mrozek, J.: JavaScript na serveru: Architektura a první Hello World. [online], říjen 2012, [cit. 28. 2. 2013]. Dostupné z: http://www.zdrojak.cz/clanky/ javascript-na-serveru-architektura-a-prvni-hello-world [29] Mrozek, J.: JavaScript na serveru: Začínáme programovat e-shop. [online], říjen 2012, [cit. 28. 2. 2013]. Dostupné z: http://www.zdrojak.cz/ clanky/javascript-na-serveru-zaciname-programovat-e-shop [30] Mrozek, J.: Proč se zajímat o Node.js. [online], leden 2012, [cit. 9. 4. 2013]. Dostupné z: http://weblog.ronnieweb.net/2012/01/proc-nodejs [31] Mrozek, J.: Začínáme s AngularJS. [online], listopad 2013, [cit. 27. 2. 2013]. Dostupné z: http://www.zdrojak.cz/clanky/ zaciname-s-angularjs [32] Nadel, B.: My Experience With AngularJS – The Super-heroic JavaScript MVW Framework. [online], leden 2013, [cit. 1. 5. 2013]. Dostupné z: http: //blog.majesticseo.com/development/flow-metrics [33] Nejčastější dotazy ke službě Google+ pro webmastery. [online], [cit. 1. 5. 2013]. Dostupné z: http://support.google.com/webmasters/bin/ answer.py?hl=cs&answer=1140194 [34] Nešetřil, J.: JavaScript na serveru: Začínáme s Node.js. [online], listopad 2010, [cit. 28. 2. 2013]. Dostupné z: http://www.zdrojak.cz/clanky/ javascript-na-serveru-zaciname-s-node-js [35] Nielsen, J.: How Users Read on the Web. [online], říjen 1997, [cit. 20. 4. 2013]. Dostupné z: http://www.nngroup.com/articles/ how-users-read-on-the-web [36] O’Dell, J.: How LinkedIn used Node.js and HTML5 to build a better, faster app. [online], červenec 2011, [cit. 28. 2. 2013]. Dostupné z: http: //venturebeat.com/2011/08/16/linkedin-node 77
Literatura [37] Overturf, C.: The Second February Mozscape Index is Live! [online], únor 2013, [cit. 20. 4. 2013]. Dostupné z: http://www.seomoz.org/blog/ the-second-february-mozscape-index-is-live [38] Parr, B.: Salesforce Acquires Ruby Cloud Platform Heroku for $212 Million. [online], prosinec 2010, [cit. 13. 3. 2013]. Dostupné z: http: //mashable.com/2010/12/08/salesforce-heroku [39] Procházka, J.; Klimeš, C.: Provozujte IT jinak. Praha: Grada Publishing, a.s., 2011, ISBN 978-80-247-4137-6, 269–271 s. [40] Prokop, M.: Podstrčení jiné stránky vyhledávači a jiné návštěvníkům. [online], prosinec 2005, [cit. 14. 3. 2013]. Dostupné z: http://vyhledavace. info/poradna/2_17_0.html#3 [41] Prokop, M.: Optimální počet klíčových slov v textu stránky. [online], červen 2007, [cit. 17. 4. 2013]. Dostupné z: http://vyhledavace.info/ seo-faq/19/hustota-slov [42] Przybilski, M.: REST - REpresentational State Transfer. [online], 2005, [cit. 13. 12. 2012]. Dostupné z: http://www.cs.helsinki.fi/u/chande/ courses/cs/MWS/reports/MichaelPrzybilski_REST.pdf [43] Purchart, V.: Dependency Injection: motivace. [online], červen 2011, [cit. 28. 2. 2013]. Dostupné z: http://www.zdrojak.cz/clanky/ dependency-injection-motivace [44] Písek, S.: HTML - začínáme programovat. Praha: Grada Publishing, a.s., 2010, ISBN 978-80-247-3117-9, 18–19 s. [45] Rodriguez, A.: RESTful Web services: The basics. [online], listopad 2008, [cit. 13. 12. 2012]. Dostupné z: https://www.ibm.com/developerworks/ webservices/library/ws-restful [46] Snížek, M.: Tisková verze stránek je stále nutná. [online], prosinec 2006, [cit. 20. 4. 2013]. Dostupné z: http://www.snizekweb.cz/weblog/ tiskova-verze/ [47] Stefanov, S.: JavaScript Patterns. Sebastopol, CA, USA: O’Reilly Media, 2010, ISBN 978-0-596-80675-0, 3–6 s. [48] Steigerwald, D.: Třídy, dědičnost a OOP v Javascriptu – I. [online], březen 2010, [cit. 25. 2. 2013]. Dostupné z: http://www.zdrojak.cz/clanky/ oop-v-javascriptu-i [49] Tiwari, S.: Professional NoSQL. Indianapolis, USA: John Wiley & Sons, 2011, ISBN 978-0-470-94224-6, 4 s. 78
Literatura [50] Vaquero, L.; Rodero-Merino, L.; Cacer, J.: A Break in the Clouds: Towards a Cloud Definition. [online], leden 2009, [cit. 10. 12. 2012]. Dostupné z: http://ccr.sigcomm.org/online/files/ p50-v39n1l-vaqueroA.pdf [51] Velička, M.: Trust flow a Citation flow v praxi. [online], říjen 2012, [cit. 18. 3. 2013]. Dostupné z: http://blog.h1.cz/aktualne/ trust-flow-a-citation-flow-v-praxi [52] W3C Plan 2014. [online], 2013, [cit. 11. 4. 2013]. Dostupné z: http:// dev.w3.org/html5/decision-policy/html5-2014-plan.html [53] Wilde, E.; Pautasso, C.: REST - From research to practice. New York: Springer, 2011, ISBN 978-1-4419-8302-2, 2–4 s. [54] Wolverton, T.: Amazon details its shopping habits. [online], květen 1999, [cit. 13. 3. 2013]. Dostupné z: http://news.cnet.com/ 2100-1017-225823.html [55] Štrupl, V.: Komplexní analýza webových stránek. [online], květen 2008, [cit. 20. 4. 2013]. Dostupné z: http://www.vaclavak.net/files/ komplexni_analyza_webovych_stranek.pdf [56] Štědroň, B.; Budiš, P.: Marketing a nová ekonomika. Praha: C. H. Beck, 2009, ISBN 978-80-7400-146-8, 65–68 s.
79
Příloha
Seznam použitých zkratek ACID Atomicity, Consistency, Isolation, Durability AJAX Asynchronous JavaScript and XML API Application Programming Interface BASE Basically Available, Soft State, Eventually Consistent BSON Binary JSON BDD Behavior-driven development CD Candidate Recommendation CERN Conseil Européen pour la recherche nucléaire CPU Central Processing Unit CRUD Create, Read, Update, Delete DI Dependency Injection DOM Document Object Model DTD Document Type Definition e2e End-to-end ECMA European Computer Manufacturers Association EJS Embedded JavaScript HATEOAS Hypermedia as the Engine of Application State HTTP Hypertext Transfer Protocol IaaS Infrastructure as a Service 81
A
A. Seznam použitých zkratek ICT Information and Communication Technologies IE Internet Explorer IoC Inversion of Control IT Information Technology JS JavaScript JSON JavaScript Object Notation MIME Multipurpose Internet Mail Extensions MVC Model-View-Controller npm Node Package Manager NoSQL Not Only SQL OCM Open Cloud Manifesto OSE Open Site Explorer PaaS Platform as a Service RDBMS Relational Database Management System REC W3C Recommendation REST Representational State Transfer RDFa Resource Description Framework in attributes SaaS Software as a Service SoC Separation of Concerns SQL Structured Query Language SSOT Single Source of Truth UI User Interface URI Uniform Resource Identifier URL Uniform Resource Locator W3C World Wide Web Consortium WD Working Draft XML Extensible Markup Language
82
Příloha
Seznam HTTP stavových kódů 5xx (chyba serveru)68 Tyto stavové kódy indikují, že při zpracovávání požadavku došlo k interní chybě serveru. Tyto chyby bývají způsobeny problémem na serveru samotném, nikoli vinou požadavku. Kód 500 Internal Server Error
Význam Interní chyba serveru
501 Not Implemented
Není implementováno
502 Bad Gateway
Nesprávná brána
503 Service Unavailable
Služba není dostupná
504 Gateway Timeout
Vypršel časový limit brány
505 HTTP Version Not Supported
Verze HTTP není podporována
68
Popis Na serveru došlo k chybě, a proto nelze požadavek splnit. Server není požadavek schopen splnit. Server může tento kód zobrazit například tehdy, když nerozpozná metodu požadavku. Server fungoval jako brána nebo proxy a obdržel neplatnou odpověď od serveru nacházejícího se výše v hierarchii. Server je momentálně nedostupný (protože je přetížený nebo vypnutý z důvodu údržby). Obvykle se jedná dočasný stav. Server fungoval jako brána nebo proxy a neobdržel včasný požadavek od serveru nacházejícího se výše v hierarchii. Server nepodporuje verzi protokolu HTTP použitou v požadavku.
http://support.google.com/webmasters/bin/answer.py?answer=40132
83
B
B. Seznam HTTP stavových kódů
1xx (provizorní odpověď) Stavové kódy oznamující provizorní odpověď a podmiňující pokračování provedením další akce ze strany žadatele. Kód
Význam
100 Continue
Pokračovat
101 Switching Protocols
Změna protokolů
Popis Žadatel by měl pokračovat v požadavku. Tímto kódem server oznamuje, že obdržel první část požadavku a čeká na zbývající část. Žadatel vyzval server ke změně protokolů a server oznamuje, že tak učiní.
2xx (úspěšné) Stavové kódy indikující, že server požadavek úspěšně zpracoval. Kód
Význam
200 OK
Úspěšné
201 Created
Vytvořeno
202 Accepted
Přijato
203 Non -Authoritative Information
Nesměrodatná informace
204 No Content
Žádný obsah
205 Reset Content
Obnovit obsah
206 Partial Content
Dílčí obsah
84
Popis Server požadavek úspěšně zpracoval. Požadavek byl úspěšně splněn a server vytvořil nový prostředek. Server požadavek přijal, ale dosud jej nezpracoval. Server požadavek úspěšně zpracoval, ale podává informace, které mohou být z jiného zdroje. Server požadavek úspěšně zpracoval, ale nezobrazuje žádný obsah. Server požadavek úspěšně zpracoval, ale nezobrazuje žádný obsah. Na rozdíl od kódu 204 tato odpověď vyžaduje, aby žadatel obnovil zobrazení dokumentu (například smazal formulář pro nové zadání). Server úspěšně zpracoval dílčí požadavek typu GET.
3xx (přesměrováno) Splnění tohoto požadavku je podmíněno provedením další akce. Tyto stavové kódy se často používají pro přesměrování.
Kód
Význam
300 Multiple Choices
Více možností
301 Moved Permanently
Trvale přemístěno
302 Found
Dočasně přemístěno
303 See Other
Viz jiné místo
305 Use Proxy
Použít server proxy
Popis Server může na základě požadavku provést více různých akcí. Server může vybrat akci na základě žadatele (uživatelský agent) nebo může server dát žadateli na výběr ze seznamu akcí. Požadovaná stránka byla trvale přemístěna jinam. Když server zobrazí toto hlášení (jako odpověď na požadavek typu GET nebo HEAD), automaticky přesměruje žadatele na nové umístění. Server právě na požadavek odpovídá stránkou z jiného umístění, ale žadatel by měl při budoucích požadavcích používat i nadále umístění původní. Tento kód se podobá kódu 301 v tom, že v případě požadavků typu GET nebo HEAD automaticky přesměruje žadatele jinam. Tento kód zobrazí server v případě, že by měl žadatel pro získání odpovědi provést samostatný požadavek typu GET na jiné umístění. U všech požadavků kromě typu HEAD provede server automatické přesměrování na nové umístění. Žadatel může získat přístup k požadované stránce pouze prostřednictvím serveru proxy. Když server vrátí tuto odpověď, uvede též server proxy, který by měl žadatel použít.
85
B. Seznam HTTP stavových kódů Kód
Význam
304 Not Modified
Nebylo upraveno
307 Temporary Redirect
Dočasné přesměrování
Popis Požadovaná stránka nebyla od posledního požadavku změněna. Když server vrátí tuto odpověď, nevrátí obsah příslušné stránky. Server na požadavek odpovídá stránkou z jiného umístění, ale žadatel by měl při budoucích požadavcích používat i nadále původní umístění. Tento kód se podobá kódu 301 v tom, že v případě požadavků typu GET nebo HEAD automaticky přesměruje žadatele jinam.
4xx (chyba požadavku) Tyto stavové kódy znamenají, že v požadavku je pravděpodobně chyba, která znemožnila standardní zpracování. Kód 400 Bad Request 401 Unauthorized 403 Forbidden
Význam Chybný požadavek
Popis Server nedokázal interpretovat syntaxi požadavku.
Nepovoleno
Požadavek vyžaduje ověření.
Zakázáno
404 Not Found
Nenalezeno
405 Method Not Allowed
Nepřípustná metoda
409 Conflict
Konflikt
Server požadavek zamítl. Server nemůže požadovanou stránku (nebo jiný zdroj) nalézt. Server tento kód zobrazuje často například tehdy, když reaguje na požadavek na stránku, která na serveru neexistuje. Metoda specifikovaná v požadavku není povolená. Server při plnění požadavku narazil na konflikt. Server musí v odpovědi zahrnout informace o konfliktu. Tento kód může server zobrazit jako odpověď na požadavek PUT, který je v konfliktu s předchozím požadavkem, spolu se seznamem rozdílů mezi oběma požadavky.
86
Kód
Význam
406 Not Acceptable
Nepřijatelné
407 Proxy Authentication Required
Vyžaduje se ověření serverem proxy
408 Request Timeout
Vypršel časový limit požadavku
410 Gone
Odstraněno
411 Length Required
Je vyžadována délka
412 Precondition Failed 413 Request Entity Too Large
Předpoklad selhal Požadavek je příliš rozsáhlý
414 Request-URI Too Long
Požadovaný identifikátor URI je příliš dlouhý
415 Unsupported Media Type
Nepodporovaný typ média
416 Requested Range Not Satisfiable
Požadovaný rozsah nelze uspokojit
417 Expectation Failed
Očekávání selhalo
Popis Požadovaná stránka nemůže poskytnout požadované vlastnosti obsahu. Tento stavový kód se podobá kódu 401 Unauthorized, ale požaduje ověření žadatele pomocí serveru proxy. Když server vrátí tuto odpověď, uvede též server proxy, který by měl žadatel použít. Při čekání na požadavek vypršel časový limit serveru. Tuto odpověď vrátí server v případě, že byl požadovaný zdroj trvale odstraněn. Podobá se kódu 404 Not Found, ale občas se používá místo kódu 404 Not Found v případě zdrojů, které existovaly, ale již neexistují. Server nepřijme požadavek bez platné hodnoty v poli záhlaví Content-Length. Server nesplňuje některý z předpokladů, které žadatel umístil do požadavku. Server nemůže požadavek zpracovat, protože je pro server příliš rozsáhlý. Požadovaný identifikátor URI (zpravidla URL) je příliš dlouhý na to, aby jej server mohl zpracovat. Požadavek je zadán ve formátu, který požadovaná stránka nepodporuje. Server zobrazí tento stavový kód, pokud reaguje na požadavek v rozsahu, který není u této stránky k dispozici. Server nemůže splnit podmínky uvedené v poli Expect v záhlaví požadavku.
87
Příloha
Dokumentace RESTful API Seznam všech testů Dotaz GET / api / tests HTTP /1.1 Host : localhost :5000 Authorization : Basic N T E 3 Z j k 2 Y j U 3 M 2 N j N z l k M D B m M D A w M D A 4 O j I 1 M D =
Odpověď HTTP /1.1 200 OK Content - Type : application / json [ { " _id " : " 51657 f23bb6516600b000008 " , " url " : " http :// www . domena . cz / " , " hostname " : " www . domena . cz " , " created " : " 2013 -01 -01 T15 :30:30.786 Z " , " word1 " : " slovo1 " , " word2 " : " slovo2 " , " result " : { " other " : { ... } , " links " : { ... } , " search " : { ... } , ... } }, { ... } ]
89
C
C. Dokumentace RESTful API
Vytvoření testu Dotaz POST / api / tests HTTP /1.1 Host : localhost :5000 Content - Type : application / json Authorization : Basic N T E 3 Z j k 2 Y j U 3 M 2 N j N z l k M D B m M D A w M D A 4 O j I 1 M D = { " url " : " http :// www . cvut . cz " , " word1 " : " CVUT " , " word2 " : " technika " }
Odpověď HTTP /1.1 201 CREATED Content - Type : application / json Location : http : // localhost :5000/ tests /51657 f23bb6516600b000008 { " _id " : " 51657 f23bb6516600b000008 " , " url " : " http :// www . cvut . cz / index . php " , " hostname " : " www . cvut . cz " , " created " : " 2013 -01 -01 T15 :30:30.786 Z " , " word2 " : " technika " , " word1 " : " CVUT " , " result " : { " other " : { ... } , " links " : { ... } , " search " : { ... } , ... } }
Úprava testu Dotaz PUT / api / tests /{ test_id } HTTP /1.1 Host : localhost :5000 Authorization : Basic N T E 3 Z j k 2 Y j U 3 M 2 N j N z l k M D B m M D A w M D A 4 O j I 1 M D = Content - Type : application / json { " word1 " : " jine_slovo1 " , " word2 " : " jine_slovo2 " }
90
Odpověď HTTP /1.1 200 OK Content - Type : application / json { " _id " : " 51657 f23bb6516600b000008 " , " _v " : ""; " url " : " http :// www . domena . cz / " , " basicUrl " : " http :// www . domena . cz / " , " hostname " : " www . domena . cz " , " created " : " 2013 -01 -01 T15 :30:30.786 Z " , " word1 " : " jine_slovo1 " , " word2 " : " jine_slovo2 " , " result " : { " other " : { ... } , " links " : { ... } , " search " : { ... } , " body " : { ... } , " head " : { ... } } }
Detail testu Dotaz GET / api / tests /{ test_id } HTTP /1.1 Host : localhost :5000 Authorization : Basic N T E 3 Z j k 2 Y j U 3 M 2 N j N z l k M D B m M D A w M D A 4 O j I 1 M D =
Odpověď HTTP /1.1 200 OK Content - Type : application / json { " _id " : " url " : " basicUrl " : " hostname " : " created " : " word1 " : " word2 " : " result " :
" 51657 f23bb6516600b000008 " , " http :// www . domena . cz / " , " http :// www . domena . cz / " , " www . domena . cz " , " 2013 -01 -01 T15 :30:30.786 Z " , " slovo1 " , " slovo2 " , { ... }
}
91
C. Dokumentace RESTful API
Smazání testu Dotaz DELETE / api / tests /{ test_id } HTTP /1.1 Host : localhost :5000 Authorization : Basic N T E 3 Z j k 2 Y j U 3 M 2 N j N z l k M D B m M D A w M D A 4 O j I 1 M D =
Odpověď HTTP /1.1 204 NO CONTENT
Smazání všech testů Dotaz DELETE / api / tests HTTP /1.1 Host : localhost :5000 Authorization : Basic N T E 3 Z j k 2 Y j U 3 M 2 N j N z l k M D B m M D A w M D A 4 O j I 1 M D =
Odpověď HTTP /1.1 204 NO CONTENT
92
Příloha
Pokyny k instalaci Následující kroky popisují zprovoznění aplikace pod operačním systémem Windows. Zprovoznění aplikace vyžaduje nainstalování platformy Node.js, databázového enginu MongoDB a WebKitu PhantomJS. Nejprve je ale zapotřebí zkopírovat zdrojové soubory z přiloženého CD kamkoliv na disk, např. do C:\nodeseo.
Node.js Instalátor Node.js je dostupný na adrese http://nodejs.org. Instalace je triviální a nevyžaduje žádná speciální nastavení. Po nainstalování a restartování PC je možné v konzoli používat příkaz node a npm. Zadáním příkazu node --version zjistíme aktuální verzi Node.js. Pokud používaná verze neodpovídá verzi 0.8.1, doporučuji stáhnout tuto verzi z adresy http://nodejs.org/dist. Downgrade lze pak provést jednoduše náhradou souboru node.exe v místě instalace (typicky C:\Program Files\nodejs). V konzoli pak zadejte v adresáři s aplikací příkazem npm install instalaci potřebných balíčků.
MongoDB MongoDB lze stáhnout na adrese http://www.mongodb.org/downloads. V závislosti na verzi operačního systému je k dispozici 32bitová i 64bitová verze MongoDB. Stažený balíček stačí rozbalit a umístit kamkoliv na disk, např. do C:\mongodb. Poté vytvořte adresářovou strukturu C:\data\db, kam se budou ukládat data. Před každým spuštěním aplikace NodeSEO je nejprve nutné spustit MongoDB přes soubor mongod.exe. Při spuštění si program mongod vytvoří zámek (C:\data\db\mongod.lock), aby jej nebylo možné spustit dvakrát. Pokud dojde k nestandardnímu vypnutí, bude zapotřebí soubor mongod.lock ručně smazat, jinak nebude možné program mongod.exe spustit. 93
D
D. Pokyny k instalaci
PhantomJS Instalátor PhantomJS lze stáhnout na adrese http://phantomjs.org. Aplikace NodeSEO byla testována na PhantomJS ve verzi 1.8.2 a 1.9.0. Po nainstalování je třeba přidat do systémové proměnné PATH cestu k aplikaci. Pod operačním systémem Windows 7 je postup následující: • Klikněte pravým tlačítkem myši na Počítač a vyberte Vlastnosti. • V levém sloupci zvolte Upřesnit nastavení systému. • Na kartě Upřesnit klikněte na tlačítko Proměnné prostředí. • V oblasti Systémové proměnné najděte proměnnou Path a dvojklikem na ní otevřete okno Úpravy systémové proměnné. • Do pole Hodnota proměnné vložte na konec řádku za středník (;) cestu do složky s nainstalovaným WebKitem PhantomJS, např. C:\phantomjs1.9.0-windows. Potvrďte změny kliknutím na tlačítko OK. • Restartujte počítač, aby se změny projevily.
Konfigurace Konfigurační proměnné můžete změnit v config/congif.json. Připojení do databáze ponechte klidně předdefinované. Do proměnné gmailLogin vyplňte Vaši gmailovou adresu (např.
[email protected]). Do proměnné gmailPass vyplňte přihlašovací heslo k gmailovému účtu. Nakonec vyplňte do proměnné pageSpeedApiKey API klíč, který získáte na adrese https://code.google. com/apis/console. Zde přejděte v levém menu na stránku Services, kde povolte službu Page Speed Online API přepnutím na ON. Na stránce API Access najdete Váš API klíč pod nadpisem Simple API Access.
Spuštění Aplikaci je možné nastartovat prostřednictvím konzole zadáním příkazu node na soubor server.js, např. tedy node C:\nodeseo\server.js (nezapomeňte před tím spustit mongod.exe). Úvodní stránka se zobrazí v prohlížeči pod adresou http://localhost:5000.
94
Příloha
Screenshoty
Obrázek E.1: Nový test
95
E
E. Screenshoty
Obrázek E.2: Nový test – spuštění
96
Obrázek E.3: Historie provedených testů
97
E. Screenshoty
Obrázek E.4: Detail testu – přehled
98
Obrázek E.5: Detail testu – obsah
99
E. Screenshoty
Obrázek E.6: Detail testu – odkazy
100
Obrázek E.7: Detail testu – rychlost
101
E. Screenshoty
Obrázek E.8: Editace testu
102
Příloha
Obsah přiloženého CD
readme.txt...................................stručný popis obsahu CD screenshots............................adresář se screenshoty aplikace src nodeseo.....................................zdrojové kódy aplikace thesis ...................... zdrojová forma práce ve formátu LATEX text ....................................................... text práce DP_Serak_Matej_2013.pdf .............. text práce ve formátu PDF video............................................videoukázky aplikace 103
F