Přejít k navigační liště

Zdroják » JavaScript » JavaScriptové MVC frameworky (reakce na článek Ondřeje Žáry)

JavaScriptové MVC frameworky (reakce na článek Ondřeje Žáry)

Články JavaScript

Jaký je současný stav MVC frameworků v JavaScriptu. Jsou tou správnou cestou? Minule nám svůj subjektivní pohled předložil Ondřej Žára, dnes na něj reaguje Daniel Steigerwald.

Nálepky:

Ondřej Žára předminulý týden napsal článek, který mne zaujal. Předně, považuji Onřeje za špičkového programátora, ale v některých názorech s ním nesouhlasím. A nebo jen špatně čtu mezi řádky, i to je možné. Co se týká přehledu frameworků, ten by vydal na samostatný článek. Mimochodem, zrovna minulý víkend jsem na podobné téma přednášel na pardubickém DevFestu.

Proč dávám přednost šablonám před DOM manipulací

Kdysi dávno jsem šablony také nepoužíval. Teď je používám skoro vždy. Proč?

Bezpečnost, XSS a vůbec

Známá věc, programátor zapomene někde escapovat string, a je problém. Se šablonovacím systémem na to myslet nemusím (tolik), viz také developers.google.com/closure/templates/docs/security.

Rychlost

innerHTML je stále nejrychlejší. V Google Closure se šablony kompilují do funkcí. Celá aplikace je tedy jeden JavaScript. Ten obsahuje kód, HTML v šablonách, texty. Třeba takový tapomat.cz, celá aplikace má jen pár desítek kb.

Události

Opravdu není nutné registrovat onclick na každý řádek tabulky. Máme event bubbling a event delegation. V Este vyrenderuji třeba seznam objednávek, a click (respektive tap event) dostane v listeneru přímo model konkrétní objednávky. Registrace bublajících událostí je velmi jednoduchá, viz demo. Díky bublání eventů můžeme obsah elementu přerenderovávat přes innerHTML kolikrát chceme, a není nutné eventy deregistrovat.

Lokalizace

V Google Closure Templates mám perfektní podporu lokalizace. Stačí si pamatovat vždy použít <msg> pro šablony a goog.getMsg pro kód, a lokalizace je hračka, i když se aplikaci rozhodnete lokalizovat poté, co je rok ve vývoji. Mimochodem, nepoužité překlady Closure Compiler při kompilaci odstraní, takže není třeba řešit bobtnání slovníků.

Pořádek

Každá šablona, respektive vykompilovaná funkce z ní, je umístěná ve svém namespace. Aplikace se skládá z features, a pomocí feature toggle a Closure Compileru můžu vykompilovat jen to, co je třeba. Příklad, mobilní verze nebude mít administraci. Jeden projekt, dva vykompilované soubory pro každé zařízení zvlášť. Veliký pokrok proti script tagům v HTML stránce!

Budoucnost a Angular

Angular se od všech ostatních MVC frameworků liší tím, že používá něco, co bude jednou součástí nativního api prohlížeče (takže to bude používat i Ondrej Žára ). Ano, šablonovací systém Angularu je něco jako polyfill pro github.com/toolkitchen/mdv. To je mimochodem důvod, proč Este nemá něco jako Angulaří šablony. Este má svoje vlastní postupy a časem bude zahrnovat i vlastní MDV polyfill.

Jmenuji se Daniel Steigerwald a pomáhám firmám i jednotlivcům s vývojem webových aplikací. Pořádám školení, která si můžete objednat na javascript-skoleni.cz. Pokud máte dotazy, napište mi.

MVC Frameworky

Framework není nic jiného, než předprogramovaná aplikace. Zajímavé je, že v Google Closure žádný jeden univerzální MVC framework není. Proč Closure nemá jeden MVC framework? Protože v Googlu má každý tým vlastní framework. Jeden pro mapy, další pro Google Docs, a tak dále. Většina JS programátorů ale nepíše mapy nebo Google Docs. Chtějí SPA (Single Page Applications). A tam narazí na mnoho již vyřešených problémů. Například routing. Ten mimochodem naprostá většina MVC frameworků řeší špatně, (krom Este MVC samozřejmě).

Onřej má tedy pravdu, že na specifické příklady se hodí framework vlastní. Ale na 80 % zbytku je dobré postavit se na záda někomu, kdo SPA MVC aplikaci už psal.

Existuje ještě třetí možnost. Pokud MVC framework není monolitický bastl, můžu si půjčit jen to, co potřebuji. Příklad. Este MVC používá este.Model, este.Collection, este.Router, este.este.storage.* a tak dále. Nicméně, ve vaší aplikaci můžete využít třeba jen este.Router a este.storage.Local.

Onřej Žára TODO MVC

TodoMVC Ondřeje Žáry je technologická hříčka. Tímto způsobem se píší příspěvky do soutěže js1k.com. Psát takto něco většího by byla katastrofa. Co když budeme chtít vyrenderovat todo v jiném pohledu? Budeme muset rozdělit soubor todo.js na model a jeho view. Co když budeme chtít zpracovávat více cest, napíšeme si vlastní router? A tak dále, ale já myslím, že Ondřej tohle ví, a zmiňuji to zde hlavně proto, aby někoho nenapadlo psát JS aplikaci podobným způsobem. Frameworky jsou dobrá věc. Neřešte, co už je vyřešené.

Este TODO MVC

TodoMVC demo napsané nad este.App. Možná vás zarazí velikost – 496 kb JavaScriptu! Ale to je v pořádku. V Closure můžeme psát velkoryse, není třeba se omezovat. Klidně můžeme použít takovouhle obří enumeraci, nebo implementaci localStorage pro IE 6 a 7. Nemyslete si ale, že jsem musel explicitně ten kód volat, přidávat script tag, nebo něco takového. Stačilo goog.require('este.storage.Local'); a můžu používat svou vlastní local storage. Closure a Este se postará o zbytek. Tento mód používáme při vývoji. Pro nasazení použijeme vykompilovanou verzi. Vykompilovaná Este TodoMVC app má 22 kb (po gzipu). Mimochodem, nemá smysl řešit velikost bez gzipu. Ten podporují všechny prohlížeče, a Closure Compiler navíc optimalizuje kód tak, aby se dobře kompresil. 22 kb se šablonama, logikou, podporou IE, MVC frameworkem, lokalizací plural rules a mnoho další. Pro srovnání, samotné jQuery má něco kolem 32 kb.

Závěr

Onřej Žára napsal pěkný článek, který snad pomůže vybrat si framework. Líbí se mi, jak šel do architektonických detailů. S jeho závěry však nesouhlasím. Zkusil jsem si oba způsoby vývoje, psát si všechno sám a reuse, a neměnil bych. V Google Closure Library je tak neskutečné množství perfentního otestovaného kódu, že by byla fakt veliká škoda jej nevyužít. Velikost a rychlost výsledné aplikace je díky Closure Compileru naprosto bezkonkurenční. Většina aplikací je menší než samotné jQuery.

Odpovědi na otázky z předchozího článku:

Rozumím tomu nástroji dobře? Dokážu v implementaci ospravedlnit existenci každé řádky svého kódu a vysvětlit, proč ho používám?

Ano, v Closure i Este mám všude podrobné testy a dema. Nevím o jiné knihovně tak dobře pokryté testy a zdokumentované.

Bude výslednému kódu rozumět i ten, kdo k němu přijde po mně? I za dva roky?

Jasně, Closure je v produkci už od roku 2007. Většina kódu se vůbec nemění, knihovna je stabilizovaná, breaking change jsem nezažil. Co se týká Este, snažím se psát hodně malých tříd, a minimalizovat breaking change. Změna signatury metody například, je navíc díky compileru bezpečná.

Volím framework proto, že je to nejlepší řešení mého problému? Nebo jen proto, že mi ho někdo doporučil a/nebo je zrovna in něco takového používat?

Volím Google Closure, a nad ním postavené Este, protože jsem napsal zilióny řádků v jQuery, Mootools, YUI, a dalších. Špatné cesty jsem si poctivě prošlapal.

Ospravedlní mi těch pár uspořených kilobajtů aplikačního kódu přítomnost frameworku, který leckdy sahá na několik set kilobajtů?

Je to naopak. :) S Closure jsou moje aplikace řádově menší než aplikace jiných frameworků. Zdrojáky jsou obrovské, ale výsledný kompilovaný script maličký.

Je pro mne práce s DOMem skutečně tolik obtížná a repetitivní, že kvůli ní musím klesnout k užití string-based šablon?

Ani ne, ale používám ji tam, kde to dává smysl. Třeba když přepínám pohledy, píšu komponentu (ale ta též může využívat šablony), a podobně. Když jde o HTML strukturu, šablony používám vždy. Je to velmi praktické a pohodlné.

Komentáře

Subscribe
Upozornit na
guest
49 Komentářů
Nejstarší
Nejnovější Most Voted
Inline Feedbacks
View all comments
Tom

Pěkný článek, ale hodně subjektivní. Připadá mi, jako kdyby autor někdy v minulosti šlápl vedle, a teď se to za každou cenu snaží nějak obhájit. Článek Ondřeje Žáry je mnohem přínosnější.

Martin Hassman

Vyčítat subjektivním článkům, že jsou subjektivní, je asi jako vyčítat seriálům, že mají více dílů. Není to bug, ale feature 8-) Cílem autorů nebylo napsat lepší článek než ten druhý autor, ale popsat svůj osobní pohled. Pokud někdo další přidá svůj, rádi ho vydáme.

Lukas

Uz je to fakt az unavujici me prijde porad a neustale od Daniela cist a poslouchat propagaci reseni postavenym na google closure a Este.js, podle me je dobre zkouset a vymyslet neco noveho, nebot kdyby kazdy pouzival jen to co je napsane a nejak vyresene tak by se nikdo, nikam neposouval. Rozhodne toto reseni ma sve vyhody ale opravdu je potreba toto neustale omilat dokola ?

Petr

Naprosto souhlasim. Ze stejneho duvodu jsem prestal chodit na jakekoli akce, kde se tento pan trpici God-modem vyskytuje. Ondrej Zara si holt dovolil kecat do tematu, o kterem smi mluvit a publikovat jen Ten, jehoz jmeno se nevyslovuje. Ano, vsechny MVC frameworky jsou na ho*no, jen Este (mimochodem, tento vyraz je v tomto kratkem clanku pouzit 22x) je dokonaly a presne z toho duvodu ma na Githubu score 25×2 a od Ase na zapad o nem nikdo nikdy neslysel… To myslim mluvi za vse :-)
Autorovi bych doporucil alespon 3x precist vynikajici clanek http://www.growjob.com/clanky-personal/mentalni-mor-vlastni-neobjektivita/

Daniel Steigerwald

Nečtete dobře. Nepsal jsem, že jsou všechny na hovno, jen jsem psal, že nemají dobrý routing, a odkázal jsem na článek, který SPA v detailu vysvětluje. Některé vlastnosti jsou implementované v Este. V ostatních frameworcích ne. To je celé.

keff

Vim ze riskuju flame, ale Dan ma v mnohem pravdu – javascriptovy framework ala Nette, tzn. ve kterem defaultni zpusob delani veci je ten dobry pro vyvojare i uzivatele, a ktery abstrahuje (dobre!) cast slozitosti platformy tak, ze o nich zacatecnik vubec nevi a pritom je udela dobre, ten tu jeste porad neni. Takze je imo dobre se bavit o tom, co tem dnesnim chybi.

Za sebe vidim v Nette vs. Este rozdil (ve frameworcich i autorech) – ten Daviduv je i pro zacatecniky, Danuv ma latku pro uzivatele nastavenou vys.

Kareves

Vypadá to, že Este v Todo MVC chybí. Chtělo by ho tam dodat, pro srovnání.

Daniel Steigerwald

Na TodoMVC Este zatím není. Plánuji ho tam dodat, ale čekám na nové TodoMVC pro jazyky, které se kompilují do JS. Addy už na tom maká.

Kareves
Daniel Steigerwald
Filip.Jirsak

Bezpečnost je snad naopak výhoda manipulace s DOMem, ne? HTML/script injection (a jeho podmnožina XSS) je přece postaveno na tom, že uživatel místo „obyčejného“ textu vloží text ve speciálním formátu, který je parserem interpretován jinak než obyčejný text. V případě manipulace s DOMem tam žádní parser není, takže není co obelstít. V případě šablon stačí udělat něco jako „“+vstup+““, a máme injection jak z čítanky.

Daniel Steigerwald

To ne. Šablony defaultně vše escapují, prosté ani jiné +vstup+ injection tak nefunguje. Musíte explicitně šabloně říct, „tohle neescapuj“. Manipulace s DOMem vypadá snadněji, stačí nepoužít innerHTML.. jenže XSS je zranitelné i pro attributy, a na to každý už nemyslí.

Filip.Jirsak

Šablony nemůžou defaultně vše escapovat, to by pak byly k ničemu. Kdybych ze šablony dostal na výstupu defaultně <p></p>, k čemu by mi šablona byla? Do atributů, které by byly zranitelné, se uživatelský vstup vkládá asi jen málokdy.

Daniel Steigerwald

Šablony jsou HTML. Automaticky se escapují proměnné do nich vkládané.

Filip.Jirsak

Pokud se proměnné vkládají tím správným způsobem. Pokud se vkládají způsobem uvedeným výše (čemuž nic nezabrání), tak escapované nejsou. Ano, šablony jsou určené k tomu, aby se mnou uvedený způsob nepoužíval – ale pořád to jen usnadňuje řešení problému, který při manipulaci s DOM prakticky neexistuje (ano, pokud budu uživatelský vstup vkládat rovnou do img/@src nebo do */@style, je to bezpečnostní díra – ale ta tam bude i při použití šablon, protože to byl musel mít šablonovací systém křišťálovu kouli, aby tohle „oescapoval“).

David Grudl

Řetězce v atributu src je escapují stejně, jako třeba v atributu title. Tj. dvojice znaků uvozovky a & se převedou na entity.

Martin Hassman

Systém tu křišťálovou kouli přeci má – ví, kam to chceme vkládat. Nevím teď jaké všechny šablonovací systémy, ale řada jich tohle opravdu rozpoznává a řeší a osobně tohle vidím jako cestu budoucnosti oproti neohrané práci s DOM.

Filip.Jirsak

Když do DOM atributu src tagu img vložím uživatelský vstup „http://mujserver.hacker.cz/sleduju-te.php“, je to bezpečnostní problém. Když tenhle vstup vložím do šablony, escapují se uvozovky a ampersand, čili se nezmění nic, a na výstupu budu mít to samé, jako s DOM, tedy stejný bezpečnostní problém. Šablonovací systém křišťálovou kouli nemá – neví, že obrázky z „http://galerie.ja.cz“ jsou OK, ale z jiných domén ne.

V tomto jsou si tedy oba přístupy rovny. Další případ jsou znaky se zvláštním významem – o těch asi píšete vy dva. Při práci s DOMem takové znaky neexistují, takže není co řešit, šablonovací systém je při správném použití možná správně escapuje. Takže tu pořád ještě zbývá prostor pro špatné použití šablonovacího systému a pro nedostatky v escapování*) – nebo-li DOM není z pohledu bezpečnosti nikdy horší, v některých případech může být lepší, a tedy v porovnání DOM a šablonovacích systémů je větší bezpečnost výhodou DOMu.

*) Udělat správné escapování pro obecné HTML interpretované v prohlížečích je velmi složité až nemožné. Prohlížeče totiž interpretují i chybný HTML kód, a každý prohlížeč to dělá jinak. Parser by tudíž musel interpretovat kód stejně, jako všechny prohlížeče – takže by pak třeba byl ve stavu „na tomto místě je Trident uvnitř komentáře, Gecko je v textu elementu a WebKit je uvnitř atributu, následující znak musím escapovat tak, aby se všude interpretoval správně“. Podle mne je nemožné takový interpret šablon napsat.

Martin Hassman

Bezpečnost v případě DOMu nebude horší, to je celkem jasné. Ta volba šablon neprobíhá z důvody bezpečnosti, ale z jiných důvodů (lepší údržba kódu apod.).

S chybným HTML kódem nebude problém, když si na něj dáme pozor, což jde.

Ale na takhle obecné úrovni se prostě špatně argumentuje „já si myslím, že šablony jsou špatné“ vs. „dělají se bez problému“. Vezměte si třeba šablony, které používá Nette (zatím v PHP, ale on je David časem do toho JavaSciprtu dostane) a ukažte na ni, co zde tvrdíte. Předveďte, že špatně escapují. Uvidíme, zda se vám to podaří. Tím se naše diskuse může posunout dál. Zdá se mi totiž, že jste pořádné šablony nezkoušel, a proto je podceňujete.

Filip.Jirsak

„Bezpečnost v případě DOMu nebude horší, to je celkem jasné.“

Mně to také připadá jasné, ale článek vyznívá přesně opačně – uvádí (větší) bezpečnost jako výhodu šablon proti DOMu.

Nemyslím si, že šablona může escapovat bez toho, aniž by věděla, zda se momentálně nachází např. v HTML kódu nebo v JavaScriptu. Ostatně v dokumentaci Nette je napsáno, že to právě tak dělá. Jenže někdy to nelze obecně rozhodnout, záleží na vykreslovacím jádru. Třeba tenhle kód:

alert(1);

Uzavírací tag komentáře je napsán chybně, je tam mezi dvojpomlčkou a většítkem mezera. Podle HTML standardu je to chybně, dvě pomlčky se v komentáři vyskytnou nesmějí, mohou pouze v kombinaci s většítkem uzavřít komentář. Jenže prohlížeče se s tím nějak popasují – a pokaždé jinak. WebKit a Trident (v plusmínus aktuálních verzích) komentář neukončí, takže celý zbytek kódu (včetně „skriptu“) je součástí komentáře – escapovat by se tedy měly jen dvojpomlčky. Gecko komentář ukončí, po něm tedy následuje skript, který se normálně provede – a escapovat by se mělo jako v JavaScriptu. Teď nastává ta správná chvíle pro křišťálovou kouli, která by měla rozhodnout, která varianta je správně.

Když z toho teď udělám šablonu, bude z toho v Gecku ukázkové XSS:
Jméno: ${loginName}

Najít tenhle rozdíl v parsování mi trvalo asi minutu, kolik jich asi je celkem?

Filip.Jirsak

Hm, bez náhledu komentáře to asi bude složité…
První kód:
<!--
- - >
<script>
alert(1);
</script>

Druhý kód:
<!-- - - > Jméno: ${loginName}

Daniel Steigerwald

Nemáte pravdu a navíc jste hrozně nestručný, což je ještě mnohem horší. Z vašich komentářů je zřejmé, že jste problematiku studoval, a snažíte se zakaždou cenu popřít mé trvzení. Co se týká mallformed HTML v šabloně, o kterém pochybuji, že by programátor napsal, protože by mu okamžitě přestal fungovat syntaxy highlight, tak vás můžu ubezpečit, že ani tak se takové HTML do šablony v Closure nedostane. Soy šablony se kompilují na serveru, a pokud je v šabloně špatné HTML, compier zařve. Vidíte. Kdybyste více studoval co jsem tu odkazoval, mohl jste si ušetřit tolik dlouhých komentářů, a nám jejich čtení.

Filip.Jirsak

Uváděl jsem příklad, ve kterém se dva parsery neshodnou na tom, co je špatné HTML. Když k tomu přidáte třetí parser (Soy šablony), situace s nekompatibilitou se určitě nezlepší.

Nestručný jsem, protože mi připadá, že se nechápeme, tak se snažím to vysvětlit podrobněji. Jinak si nedovedu vysvětlit, že by někdo myslel vážně tvrzení, že šablony jsou z pohledu XSS bezpečnější, než manipulace s DOM. Je to stejné, jako by někdo tvrdil, že escapování v SQL dotazech je bezpečnější, než binding proměnných. V případě SQL už se na to přišlo, že escapování problém neřeší, ale jenom maskuje – a zpravidla ne moc úspěšně. Je potřeba na to u JavaScriptu přicházet znova?

Martin Hassman

Jestli se ty kódy nyní zobrazují správně, tak tam žádný problém nevidím. loginName se normálně zaescapuje, pokud to programátor cíleně nezakáže. Zkuste nějaký příklad, který si opravdu vyzkoušíte. Myslím OPRAVDU vyzkoušíte. Máme tu v ČR stovky programátorů, kteří těmto šablonám věří (patří k nim), pokud ukážete opak, natrhneme nám všem tričko a dokážete, že David Grudl je lhář, když je obhajuje. Nevěřím, že se vám to povede. Ale zkuste to. Ne zde v komentáři, vytvořte a pošlete sem funkční příklad, který si může každý vyzkoušet a uvidět na vlastní oči, že tam je problém. Věnujete tomu těch pár minut a zvedenete onu rukavici?

David Grudl

Tak to už je trošku nefér.

Jednak, Filip má naprostou pravdu, že argument týkající se XSS je vůči DOM lichý. Protože jsou to právě šablony, kdo prostor pro tuhle díru vytvářejí.

Stejně tak může existovat kód, který uvede parser v omyl, ať už jde o parser v browseru nebo v šablonách. Řešením je být striktní a nic jiného než well formed HTML neakceptovat (a negenerovat).

A nakonec, není šťastné používat slovo „lhát“ tam, kde patří „mýlit se“. Pokud se třeba v Latte najde chyba, rád ji opravím, ale nedělá to ze mě lháře, dokonce ani mýlícího se, neb jsem nikdy netvrdit, že je to 100% bezchybné.

Martin Hassman

„Bezpečnost v případě DOMu nebude horší, to je celkem jasné.-Mně to také připadá jasné, ale článek vyznívá přesně opačně“

Dobrý šablonovací systém bude mít stejnou bezpečnost jako DOM (nenapadá mne teoretický případ, kdy by ji měl větší). Onou větší bezpečnostní šablon se (běžně) myslí oproti stávajícím postupům a la skládání stringů nebo obecně jakýmkoliv postupům, ve kterých nedochází k automatickému escapování (což je nejčastěji právě ono skládání stringů – v různých podobách).

Martin Hassman

Hergot, to vnořování komentářů je příliš omezené a vyvolává to zmatky (opravíme).

Davide, já Filipovi srovnání s XSS nijak nerozporuji. A lhát vs mýlit se je na hlubší debatu, kterou zde rozjíždět nechci.

Ondřej Žára

Toto vlákno již skutečně ztratilo na přehlednosti. Předně se v něm ale dle mého názoru ztratila podstata jeho vzniku, a to vzájemné nepochopení principu escapování v JS šablonách.

Filip zcela korektně poukazuje na to, že „kontextově“ escapovat fragmenty HTML na úrovni stringu není možné, právě s ohledem na nejednoznačnost kontextu.

Filipe, nejčastěji používané JS šablony ale fungují na mnohem prostějším principu – jsou zcela bezkontextové a všechny stringy paušálně proženou převodem vyjmenovaných znaků na entity, hotovson. Pokud si to uživatel explicitně vynutí, žádné escapování se nekoná – a hotovo: buď vše, nebo nic.

Toto je mimochodem také jedna z partií šablonovacích systémů, se kterou mám koncepční problém. V tomto směru mi řádově více vyhovuje přístup, kdy direktivou změním bloku šablonového kódu jeho „content type“, tj. escapovací algoritmus. Jednak je tato změna aplikována na všechna nahrazení v bloku, druhak je možno provádět nějakou parametrizaci, tj. nabízet celou řadu takových escapů – ne jen „HTML entity“ a „nic“.

David Grudl

A přesně tak funguje i kontextové escapování, jako je v Googlích šablonách a v Nette Latte (o jiných nevím). Jen místo speciální direktivy jednoduše napíšeš třeba HTML značku SCRIPT a kontext se v něm přepne. Prostě víc user friendly řešení.

Ondřej Žára

…a pokud tedy otevřu značku SCRIP> a v ní ještě nějakou haluz (jak psal Filip, nejednoznačně uzavřený komentář či tak něco), kdo mi jednoznačně řekne, které escapování zrovna systém použije? Jistě to ten systém bude dělat deterministicky a dle platné dokumentace, ale padá tím bijekce escapování na interpretaci v prohlížeči (páč tam to každý může udělat jinak).

David Grudl

Tam si otvírej jaké haluze chceš dle libosti, a jakmile se ojeví </, jsme zase v HTML ;)

Filip.Jirsak

Ať jsou šablony jednoduché bezkontextové, nebo se snaží automaticky rozpoznávat kontext, vždy mají nějaké limity – kód, který už neodhadnou správně, a pokud ho programátor extra neošetří, zůstane v programu bezpečnostní díra. Což je pro mne ten největší problém – automatické escapování má sloužit k tomu, aby na to programátor nemusel myslet – jenže zároveň by měl umět rozpoznat ty problematické případy, tedy by měl na escapování myslet neustále a vedle způsobu zpracování v prohlížečích ještě znát způsob zpracování v parseru šablon.

Jednu bezpečnostní výhodu automatickému escapování (oproti ručnímu) přiznávám: čím lepší automat, tím je statisticky menší pravděpodobnost, že se v daném programu objeví zapeklitá šablona, se kterou si neporadí.

Z tohoto důvodu podle mne ani sebelepší escapovací systém použitý v šablonách nebude nikdy tak bezpečný, jako DOM. Může se mu limitně blížit – ale pořád hrozí, že se někde objeví nějaký webový prohlížeč, který bude mít jiný parser a nějaký chybný kód bude interpretovat jinak. Představte si to třeba na podmíněných komentářích v MSIE. Před jejich příchodem mohl escapovač klidně předpokládat, že uvnitř HTML komentáře stačí escapovat dvojpomlčky. Od MSIE 5 ale najednou můžete mít uvnitř komentáře třeba JavaScript.

Jinak problém s escapováním byl třeba i v PHP a escapováním MySQL dotazů. A to je SQL jednoduchý jazyk a cílový parser je ten jediný v MySQL serveru. Přesto se nepodařilo udělat parser v PHP tak, aby dával za všech okolností přesně stejné výsledky jako ten v MySQL – čímž se otevřel prostor pro SQL injection. Nedělám si iluze, že v případě HTML by se to podařilo.

Filip.Jirsak

David Grudl: pokud si nějaký escapovací systém bude myslet, že po libovolném výskytu </ ve skriptu je zase v HTML, myslí si to jinak, než nejpoužívanější prohlížeče. Pokud jste nemyslel výskyt </ v určitém kontextu skriptu…
<script>
console.log("</");
console.log("Stále jsme ve skriptu.");
</script>

David Grudl

Chtěl jsem napsat automatické escapování má sloužit k tomu, aby na to programátor nemusel myslet – jenže zároveň by měl umět rozpoznat ty problematické případy

Zatímco bez automatického escapování musí programátor správně rozpoznat vše, vždy a bez jediné chyby. V praxi se proto ukazuje, že je řádově větší pravděpodobnost, že programátor zapomene nebo špatně nastaví kontext ručně, než že to udělá špatně automat. Proto je taky XSS stále nejrozšířenější dírou. (Ale nikoliv s Googlími a Latte šablonami).

> Z tohoto důvodu podle mne ani sebelepší escapovací systém použitý v šablonách nebude nikdy tak bezpečný, jako DOM.

Tak teď už se v tom trošku motáš, řeč je o šablonách, nikoliv DOM. Viz http://www.zdrojak.cz/clanky/javascriptove-mvc-frameworky-reakce-na-clanek-ondreje-zary/?show=comments#comment-24402

> Představte si to třeba na podmíněných komentářích v MSIE. Před jejich příchodem mohl escapovač klidně předpokládat, že uvnitř HTML komentáře stačí escapovat dvojpomlčky. Od MSIE 5 ale najednou můžete mít uvnitř komentáře třeba JavaScript.

Když jsi teda znovu otevřel téma DOM, ukaž mi prosím, jak v DOM řešíváš podmíněné IE komentáře obsahující HTML a JavaScript.

David Grudl

errata: (nechápu proč to tu žere znaky)

Chtěl jsem napsat automatické escapování má … (a dál pokračuje tvůj citát)

David Grudl

Kurva, na to kašlu.

Prostě to slovo SKRYPT se mi tu požírá, pak se mi požírá odřádkování, odrážka atd.

Filip.Jirsak

Myslel jsem, že se tu celou dobu řeší, zda je DOM oproti šablonám (s automatickým escapovánímodolnější vůči XSS útokům (jak tvrdím já), zda je odolnost srovnatelná (jak tvrdí Martin Hassman), nebo zda jsou odolnější šablony (jak tvrdí Daniel Steigerwald v článku).

Podmíněné komentáře při manipulaci s DOMem neřeším, použiju místo toho if přímo v JavaScriptu.

To rozpoznávání problematických případů je přesně to, co podle mne v praxi nebude nikdy pořádně fungovat. Souhlasím, že automatické escapování je většinou lepší než ruční escapování. Ale trvám na tom, že ještě daleko lepší řešení – a jediné, které může bezpečnost opravdu zaručit – je takové, kde žádné escapování vůbec není potřeba. Což jde mimochodem udělat i s pomocí šablon – akorát to nebudou šablony s volným textem, ale šablony, které na výstupu generují DOM. Nejrozšířenějším příkladem jazyka pro takové šablony je XSLT.

Širo

Nesúhlasím vo veľa veciach a tobôž sa mi nepáči ukážka TodoMVC v EsteJS, pretože na takú malú ukážku Todo listu je nejako priveľa JavaScriptových súborov, nie?
http://este.jit.su/client/deps.js

Myslím si, že toto sa nikdy nestane: „AngularJS … co bude jednou součástí nativního api prohlížeče …“ … To sa nepodarilo ani jQuery a neverím, že také niečo ako AngularJS bude natívnou súčasťou prehliadača. Ak tak – tak maximálne Google prehliadača.

Martin Hassman

Co se týče HTML šablon obecně, tak snaha dostat je do prohlížeče tu byla i je nadále. Poslední pokus jsem zaznamenal na http://www.html5rocks.com/en/tutorials/webcomponents/template/ Zda se opravdu někdy do prohlížeče dostanou, to není vůbec jasné, osobně považuji za pravděpodobné, že k tomu v nějaké podobě (zatím nevíme jaké) časem dojde.

Daniel Steigerwald

Deps obsahuje všechny potenciálně použitelné soubory, ne jen ty nutně použité. Generuje se automaticky, takže není třeba ručně udržovat cesty k souborům.

Daniel Steigerwald

Až na to, že už se to stalo. MDV, které principem vychází z Angulařích šablon, už je součástí Chrome Canary. Ostatní prohlížeče budou následovat nebo dostanou polyfil.

Širo

Ospravedlňujem sa, zle som to prečítal … Ja som nemyslel na šablony AngularJS, ale na celý framework AngularJS … v článku je napísané „že používá něco“, takže pardón.

David Grudl

> Například routing. Ten mimochodem naprostá většina MVC frameworků řeší špatně.

Co myslíš tím špatným routingem? Je ten odkaz správně, na odkazové stránce se totiž termín routing (ani nic, v čem bych zaznamenal souvislost) nevyskytuje.

Daniel Steigerwald

Jde o tento článek https://medium.com/joys-of-javascript/4353246f4480 Termín související s routingem má dokonce v názvu „Beyond pushState“. pushState (a hashchange) se pro routing klientských apps používá. Stručně o co jde. Naprostá většina JS MVC frameworků na změnu url prostě jen vymění jeden div element za jiný. To je ale málo a má to dost nešťastné UX konsekvence. Když jsem kdysi implementoval routing, ještě před existencí Este, hrozně mne štvalo takto naivní řešení. Příklad, klikneš na jeden odkaz, MVC rovnou zobrazí novou stránku, a na ní se začne něco načítat s progress barem. Co když se nic nenačte? Co když si kliknul špatně, a chceš ještě před dokončením načítání kliknout jinam? V Este každý presenter vrací promise, aby tak mohl dát vědět, jak načítání stránky dopadlo. Příklad http://este.jit.su/bower_components/este-library/demos/app/simple/#/product/1
Dan Pupius, mimochodem jeden z autorů Closure, teď už mimo Google, tento pattern nazval Pending navigations – Block UI rendering until data is loaded. Další věc je udržení scroll pozice, něco, co Twitter vesele ignoruje už roky. Pokud vlezeš na detail, chceš aby tě back button vrátil na předchozí scroll pozici, ne na začátek. Atd. Este neřeší všechno v článku zmíněné, nicméně postupně tam zbývající body doplňuji. Hodně mi v tom pomáhá, že Este routing je async by default.

David Grudl

Aha, nenapadlo mě, že v JS se pod routingem rozumí i samotné zobrazení předchozí stránky. Očekával bych, že tohle bude mít na starosti MVC, podobně jako když klikneš na novou stránku.

Srigi

Pekny clanok o tejto problematike uverejnili aj vyvojari mobilneho Financial Times.

David Grudl

Nebo velmi podrobně před dvěma lety Jakub Vrána http://webexpo.cz/praha2011/prednaska/ajaxizace/. Jen škoda, že není video, pouze slajdy.

Daniel Steigerwald

Však má, a řeší to povětšinou nešťastně.

Filip Procházka

Tip pro Dana a redaktory Zdrojáku: Když vkládáte odkazy na github do článku, zkuste je zafixovat na nějaký aktuální commit. Všechny Danovi odkazy na este jsou rozbité.

Enum a statická analýza kódu

Mám jednu univerzální radu pro začínající programátorty. V učení sice neexistují rychlé zkratky, ovšem tuhle radu můžete snadno začít používat a zrychlit tak tempo učení. Tou tajemnou ingrediencí je statická analýza kódu. Ukážeme si to na příkladu enum.