11.07.2015 Views

th class="app-grid-thead-th" - Jfokus

th class="app-grid-thead-th" - Jfokus

th class="app-grid-thead-th" - Jfokus

SHOW MORE
SHOW LESS
  • No tags were found...

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

RepoBygge war/ear/klumpApplikationsserverMonday, February 4, 13@joakimkemeny & @johnwilander


Repo 1Repo 2Bygge 1 zip/klumpWebbserverBygge 2 war/ear/klumpApplikationsserverMonday, February 4, 13@joakimkemeny & @johnwilander


KundStatiska filer,cache:adeWebbserverApplikationsserver@joakimkemeny & @johnwilanderMonday, February 4, 13


KundData, typiskt JSON(ingen jsp/aspx/html)WebbserverApplikationsserverMonday, February 4, 13@joakimkemeny & @johnwilander


Repo 1Repo 2Utmaning:Hålla klient och server i synk.Taggning, bygge, driftsättning, rollback …WebbserverApplikationsserverMonday, February 4, 13@joakimkemeny & @johnwilander


DEMOVårt lilla REST-apiMonday, February 4, 13@joakimkemeny & @johnwilander


DEMOSkapa ett webbprojektMonday, February 4, 13@joakimkemeny & @johnwilander


Repo 1WebbserverKonkatenerade,minifierade skript irätt ordningGenererad,minifierad cssIkoner i sprite mapGzip:at och klartVersionerat med filellerkatalognamnMonday, February 4, 13@joakimkemeny & @johnwilander


Konkateneringoch minifieringMonday, February 4, 13@joakimkemeny & @johnwilander


Konkateneringoch minifieringMan kan vilja skilja på egnaskript och tredjepartsskript,inte minst för att kunna cache:atredjepartsskript hårdare.Monday, February 4, 13@joakimkemeny & @johnwilander


Konkateneringoch minifieringMålet är att minimera antaletHTTP-anrop och storleken pådata som transporteras.Monday, February 4, 13@joakimkemeny & @johnwilander


Verktyg för konkateneringoch minifiering• Google Closure Compiler• UglifyJS• require.jsUtför konkatenering och minifiering medClosure Compiler eller UglifyJSMonday, February 4, 13@joakimkemeny & @johnwilander


equire.js – import ochnamnrymd i JavaScriptMonday, February 4, 13@joakimkemeny & @johnwilander


equire(["backbone","underscore","models/CartModel","text!templates/CartItem.html"],function (Backbone, _, CartModel,cartItemTemplate) {// Kod som är beroende av Backbone etc});Monday, February 4, 13@joakimkemeny & @johnwilander


Filsystemet, ungefär som Javapaketrequire(["backbone","underscore","models/CartModel","text!templates/CartItem.html"],function (Backbone, _, CartModel,cartItemTemplate) {// Kod som är beroende av Backbone etc});Monday, February 4, 13@joakimkemeny & @johnwilander


equire(["backbone", Lokalt namn, ungefär som"underscore", dependency injection"models/CartModel","text!templates/CartItem.html"],function (Backbone, _, CartModel,cartItemTemplate) {var model = new CartModel();});Monday, February 4, 13@joakimkemeny & @johnwilander


Definiera nya moduler som blir tillgängligadefine(["backbone","underscore","models/CartModel","text!templates/CartItem.html"],function (Backbone, _, CartModel,cartItemTemplate) {var CartItemView = …;…});return CartItemView;Monday, February 4, 13@joakimkemeny & @johnwilander


CartItemView.jsMonday, February 4, 13@joakimkemeny & @johnwilander


index.html utan någotsom require.js…… manuellt, i rätt ordning.Monday, February 4, 13@joakimkemeny & @johnwilander


index.html medrequire.jsMonday, February 4, 13@joakimkemeny & @johnwilander


index.html medrequire.js require.config({…pa<strong>th</strong>s : {jquery : "vendor/jquery.min",backbone : "../components/backbone/backbone-min",underscore : "../components/underscore/underscore"}});require(["<strong>app</strong>"], function (App) {App.start();});main.jsMonday, February 4, 13@joakimkemeny & @johnwilander


DEMO require.js +underscore templatesMonday, February 4, 13@joakimkemeny & @johnwilander


JavaScriptMonday, February 4, 13@joakimkemeny & @johnwilander


Model View ControllerJavaScriptMonday, February 4, 13@joakimkemeny & @johnwilander


Model View ControllerJavaScriptDOM $().html() ???Monday, February 4, 13@joakimkemeny & @johnwilander


JavaScript MV*Monday, February 4, 13@joakimkemeny & @johnwilander


JavaScript MV*Monday, February 4, 13@joakimkemeny & @johnwilander


Backbone.jsEmber.jsJavaScript MV*AngularJSKnockoutJSMonday, February 4, 13@joakimkemeny & @johnwilander


Backbone.jsMonday, February 4, 13@joakimkemeny & @johnwilander


Backbone.js• Models / Collections- Triggers events when changedMonday, February 4, 13@joakimkemeny & @johnwilander


Backbone.js• Models / Collections- Triggers events when changed• Views- Listen to eventsMonday, February 4, 13@joakimkemeny & @johnwilander


Backbone.js• Models / Collections- Triggers events when changed• Views- Listen to events• RoutersMonday, February 4, 13@joakimkemeny & @johnwilander


Modelsvar ProductModel = Backbone.Model.extend({urlRoot : "/api/product",defaults : {name : null,price : null}});Monday, February 4, 13@joakimkemeny & @johnwilander


Modelsvar product = new ProductModel({name : "Green <strong>app</strong>les",price : 12,});product.save();@joakimkemeny & @johnwilanderMonday, February 4, 13


Modelsvar product = new ProductModel({name : "Green <strong>app</strong>les",price : 12,});product.save();product.set("name", "Red <strong>app</strong>les");product.save({"name"}, {patch:true});Monday, February 4, 13@joakimkemeny & @johnwilander


Modelsvar product = new ProductModel({name : "Green <strong>app</strong>les",price : 12,});product.save();product.set("name", "Red <strong>app</strong>les");product.save({"name"}, {patch:true});product.destroy();Monday, February 4, 13@joakimkemeny & @johnwilander


Collectionsvar ProductCollection =Backbone.Collection.extend({url : "/api/product",});model : ProductModelMonday, February 4, 13@joakimkemeny & @johnwilander


CollectionsMonday, February 4, 13@joakimkemeny & @johnwilander


Collectionsvar products = new ProductCollection();products.fetch();Monday, February 4, 13@joakimkemeny & @johnwilander


Collectionsvar products = new ProductCollection();products.fetch();var product = products.get(1);Monday, February 4, 13@joakimkemeny & @johnwilander


Viewsvar ProductsView = Backbone.View.extend({el : "#products",initialize : function () {},<strong>th</strong>is.render();render : function () {<strong>th</strong>is.$el.html("…");}});Monday, February 4, 13@joakimkemeny & @johnwilander


Viewsvar ProductsView = Backbone.View.extend({el : "#products",initialize : function () {<strong>th</strong>is.render();<strong>th</strong>is.listenTo(<strong>th</strong>is.collection,"add change remove", <strong>th</strong>is.render);},…Monday, February 4, 13@joakimkemeny & @johnwilander


Viewsvar productsView = new ProductsView({});collection : new ProductCollection()Monday, February 4, 13@joakimkemeny & @johnwilander


Routervar Router = Backbone.Router.extend({routes : {"product" : "listProducts","product/:id" : "showProduct"},…Monday, February 4, 13@joakimkemeny & @johnwilander


RouterlistProducts : function () {var products = new ProductCollection();products.fetch({success : function(products) {new ProductsView({collection : products;}}});},…Monday, February 4, 13@joakimkemeny & @johnwilander


RoutershowProduct : function (id) {var product =new ProductModel({ id : id });model.fetch({success: function(product) {new ProductView({model : product}}});}});Monday, February 4, 13@joakimkemeny & @johnwilander


DEMO Backbone.jsMonday, February 4, 13@joakimkemeny & @johnwilander


CORSvar req = new XMLHttpRequest();req.open(me<strong>th</strong>od, crossDomainUrl);req.send();Sandboxed iframespostMessage APIo<strong>th</strong>erFrameOrWindow.postMessage(’{"action": "purchase", "item": 34443}’,"http://3rdparty.net");Monday, February 4, 13@joakimkemeny & @johnwilander


Cross-Origin ResourceSharing, CORS15+22+3.2+10+5.1+12+2.1+Visst stöd iIE8 och IE9Monday, February 4, 13http://caniuse.com/#search=cors@joakimkemeny & @johnwilander


CORS är i principcross-origin-AjaxMonday, February 4, 13@joakimkemeny & @johnwilander


CORS• Servern måste ge behörighet i svarsheaders:Access-Control-Allow-Originallowed.domain.com• HTTP GET/POST funkar som normal Ajax• Andra HTTP-metoder eller GET/POSTmed egna headers kräver en s.k. preflight• Variabel för att klienten ska skicka cookies:xhr.wi<strong>th</strong>Credentials = true;Monday, February 4, 13@joakimkemeny & @johnwilander


Låt oss se vad 2013 innebärom vi fortfarande kör en …CORS-omedvetenserverMonday, February 4, 13@joakimkemeny & @johnwilander


CORS-omedveten serverKlientServerAjax GETInga cookiesSer ut som ennormal GET.Har en pålitligOrigin-header.Ombehörighetsheadersaknasså får klienteninget svar.Om det intefinns logik förbehörighet såsvarar denbara.Monday, February 4, 13@joakimkemeny & @johnwilander


CORS-omedveten serverKlientServerAjax POSTInga cookiesSer ut som ennormal POST.Har en pålitligOrigin-header.Ombehörighetsheadersaknasså får klienteninget svar.Om det intefinns logik förbehörighet såsvarar denbara.Monday, February 4, 13@joakimkemeny & @johnwilander


CORS-omedveten serverKlientServerAjax +wi<strong>th</strong>Credentials =true;CookiesSer ut som ettnormalt anrop.Har en pålitligOrigin-header.Ombehörighetsheadersaknasså får klienteninget svar.Om det intefinns logik förbehörighet såsvarar denbara.Monday, February 4, 13@joakimkemeny & @johnwilander


CORS-omedveten serverKlientServerAjax +setRequestHeader('X-Requested-Wi<strong>th</strong>','XMLHttpRequest');Preflight-anropOPTIONS-anrop medAccess-Control-Request-Me<strong>th</strong>od:GET/POSTOmbehörighetsheadersaknasså anroparklienten aldrig.Om det intefinns logik förbehörighet såsvarar denbara.Monday, February 4, 13@joakimkemeny & @johnwilander


2013 borde vi istället köra enCORS-medvetenserverMonday, February 4, 13@joakimkemeny & @johnwilander


CORS-medveten serverKlientServerAjax +wi<strong>th</strong>Credentials =true;CookiesSer ut som ettnormalt anrop.Har en pålitligOrigin-header.Ombehörighetsheaderfinnsså får klientensvaret.Behörighetskollaroriginoch lägger tillAccess-Control-Allow-OriginMonday, February 4, 13@joakimkemeny & @johnwilander


Det här betyder att …• Servrar som inte kollar origin-headern haringen aning om att det är cross-origin Ajax.• Egna headers såsom Ajax-headern är ipraktiken döda vid CORS eftersomutvecklare vill undvika preflight-anrop.• Attackerare kan nu utföra CSRF utan imgelementeller formulärpostning.Monday, February 4, 13@joakimkemeny & @johnwilander


postMessage15+22+3.2+Visst stöd iIE8 – IE105.1+12+2.1+Monday, February 4, 13http://caniuse.com/#search=postMessage@joakimkemeny & @johnwilander


postMessage• Möjliggör strängbaserad kommunikationmellan frames och fönster• Man behöver en handle till mottagaren föratt kunna skicka ett meddelande• Mottagaren vitlistar vilka källor denaccepterar meddelanden frånMonday, February 4, 13@joakimkemeny & @johnwilander


postMessage// Sending messages requires a handle to <strong>th</strong>e receiving endvar popup = window.open("http://o<strong>th</strong>er.1-liner.org", "_blank");popup.postMessage("Luke, I am your fa<strong>th</strong>er.","http://o<strong>th</strong>er.1-liner.org");// Receiving messages requires an event listenerreceiveMessage = function(event) {if (event.origin !== "http://o<strong>th</strong>er.1-liner.org") {return;}console.log(event.data);}window.addEventListener("message", receiveMessage, false);Monday, February 4, 13@joakimkemeny & @johnwilander


postMessage// Sending messages requires a handle to <strong>th</strong>e receiving endvar popup = window.open("http://o<strong>th</strong>er.1-liner.org", "_blank");popup.postMessage("Luke, I am your fa<strong>th</strong>er.","http://o<strong>th</strong>er.1-liner.org");// Receiving messages requires an event listenerreceiveMessage Handle till = function(event) Man { specificerarif (event.origin !== "http://o<strong>th</strong>er.1-liner.org") {mottagandereturn;även domän så}fönster console.log(event.data);eller att fönstret eller}frameframe:en intewindow.addEventListener("message", receiveMessage, false);har laddats omMonday, February 4, 13@joakimkemeny & @johnwilander


postMessage// Sending messages requires a handle to <strong>th</strong>e receiving endvar popup = window.open("http://o<strong>th</strong>er.1-liner.org", "_blank");popup.postMessage("Luke, I am your fa<strong>th</strong>er.","http://o<strong>th</strong>er.1-liner.org");// Receiving messages requires an event listenerreceiveMessage = function(event) {if (event.origin !== "http://o<strong>th</strong>er.1-liner.org") {return;}console.log(event.data); Event-lyssnaren för}window.addEventListener("message", receiveMessage, false);att ta emotmeddelanden måstekolla att meddelandetkommer från enMonday, February 4, 13betrodd källa@joakimkemeny & @johnwilander


Först, sluta använda …• Jsonp• document.domain-tricket• img-tricketMonday, February 4, 13@joakimkemeny & @johnwilander


Implementera CORSserver-side nuAjax +wi<strong>th</strong>Credentials =true;KlientCookiesServerKolla alltidorigin headerOmbehörighetsheaderfinnsså får klientensvaret.Tillåtanropandedomän utifrånen vitlista.Monday, February 4, 13@joakimkemeny & @johnwilander


DEMO CORSMonday, February 4, 13@joakimkemeny & @johnwilander


WebSockets• HTML5• Dubbelriktad kommunikation- Full duplex• Liten overhead• BrandväggsvänligMonday, February 4, 13@joakimkemeny & @johnwilander


KlientServerMonday, February 4, 13@joakimkemeny & @johnwilander


KlientServerGET ws://local.communityhack.org/wsOrigin: http://local.communityhack.orgConnection: UpgradeHost: local.communityhack.orgSec-WebSocket-Key: uRovscZjNol/umbTt5uKmw==Sec-WebSocket-Protocol: modernwebSec-WebSocket-Version: 13Upgrade: websocketMonday, February 4, 13@joakimkemeny & @johnwilander


KlientServerGET ws://local.communityhack.org/wsOrigin: http://local.communityhack.orgConnection: UpgradeHost: local.communityhack.orgSec-WebSocket-Key: uRovscZjNol/umbTt5uKmw==Sec-WebSocket-Protocol: modernwebSec-WebSocket-Version: 13Upgrade: websocketConnection: UpgradeSec-WebSocket-Accept: rLHCkw/SKsO9GAH/ZSFhBATDKrU=Sec-WebSocket-Protocol: modernwebUpgrade: WebSocketMonday, February 4, 13@joakimkemeny & @johnwilander


Text messageMonday, February 4, 13@joakimkemeny & @johnwilander


0x00Text message0xFFMonday, February 4, 13@joakimkemeny & @johnwilander


0x00Text message0xFFvar ws = new WebSocket("ws://local.communityhack.org");ws.onopen = function (e) { … };ws.onclose = function (e) { … };ws.onmessage = function (e) {console.log(e.data);};ws.send("WebSocket");ws.close();Monday, February 4, 13@joakimkemeny & @johnwilander


WebSockets6+14+6.0+IE106+12.1+No!Monday, February 4, 13http://caniuse.com/#search=websockets@joakimkemeny & @johnwilander


Stora ramverk vsmikroramverkMonday, February 4, 13@joakimkemeny & @johnwilander


dojo-release-1.8.3.zip 11 Mbext-4.1.1a-gpl.zip 45,7 Mbext-all.js 1 Mbyui_3.8.1.zip 28,1 MbMonday, February 4, 13@joakimkemeny & @johnwilander


FörenklatDOM-apiTemplates& shimsWidgetsMVC@joakimkemeny & @johnwilanderMonday, February 4, 13


underscoreModernizrjQueryFörenklatDOM-apiTemplates& shimsWidgetsMVC@joakimkemeny & @johnwilanderMonday, February 4, 13


HandlebarsFörenklatMustachDOM-apiTemplates& shimsWidgetsMVC@joakimkemeny & @johnwilanderMonday, February 4, 13


FörenklatDOM-apiTemplates& shimsEmberBackboneAngularWidgetsMVC@joakimkemeny & @johnwilanderMonday, February 4, 13


FörenklatDOM-apiTemplates& shimsWidgetsMVCSpine@joakimkemeny & @johnwilanderMonday, February 4, 13


FörenklatDOM-apiTemplates& shimsWidgetsMVCBootstrapjQuery UI@joakimkemeny & @johnwilanderMonday, February 4, 13


FörenklatDOM-apiTemplates& shimsExt JSDojoYUIWidgetsMVC@joakimkemeny & @johnwilanderMonday, February 4, 13


Ramverk som gör anspråkpå alltihop lämpar sig bästför nyskrivna, sammanhållna<strong>app</strong>likationer utanmashup-beteende.Monday, February 4, 13@joakimkemeny & @johnwilander


Om ni ska integrera legacykod,någon halvhemligCMS-produkt eller harfunktion/innehåll fråntredjepart så ärmikroramverk bättre.Mikroramverk ”tar inteöver” hela <strong>app</strong>likationen.Monday, February 4, 13@joakimkemeny & @johnwilander


LinkedIn utvärderadetemplate-ramverk 2011http://engineering.linkedin.com/frontend/client-side-templating-<strong>th</strong>rowdown-mustache-handlebars-dustjs-and-moreMonday, February 4, 13@joakimkemeny & @johnwilander


Vi utvärderade <strong>grid</strong>:ar2012Monday, February 4, 13@joakimkemeny & @johnwilander


När formgivningen ochinteraktionsmönstrenblir tuffa så skadas ofta denunderliggande semantiken.-soppa är inte bra.Granska den genererademarkup:en.Monday, February 4, 13@joakimkemeny & @johnwilander


NamnSaldoDisponibelt beloppNamnSaldoDisponibelt beloppMassa pengar kontot- 4019146312,50-50 002,50…Visa alla konton@joakimkemeny & @johnwilanderMonday, February 4, 13


NamnSaldoDisponibelt beloppFasta tabellhuvudenären klassiskNamnutmaning.SaldoDisponibelt beloppFörstörsemantiken.Massa pengar kontot- 4019146312,50-50 002,50…Visa alla konton@joakimkemeny & @johnwilanderMonday, February 4, 13


NamnSaldoDisponibelt beloppGöm detfasta tabellhuvudetförsynskadade.NamnSaldoDisponibelt beloppMassa pengar kontot- 4019146312,50-50 002,50…Visa alla konton@joakimkemeny & @johnwilanderMonday, February 4, 13


DupliceratabellhuvudetNamnSaldoDisponibelt beloppsemantisktkorrektmen style:aNamnbort detSaldoDisponibelt beloppgrafisktMassa pengar kontot- 4019146312,50-50 002,50…Visa alla konton@joakimkemeny & @johnwilanderMonday, February 4, 13


Ge alla cssreglerenNamnSaldoDisponibelt beloppnamnrymdför attunvikakonflikterNamnoch överskrivningSaldoDisponibelt beloppMassa pengar kontot- 4019146312,50-50 002,50…Visa alla konton@joakimkemeny & @johnwilanderMonday, February 4, 13


Dålig webbarkitekturCSSJavaScriptHTMLCSSHTMLJavaScriptJavaScriptHTMLCSSMonday, February 4, 13@joakimkemeny & @johnwilander


Bra webbarkitekturCSS på filImportCSSHTMLJavaScript på filJavaScriptMonday, February 4, 13@joakimkemeny & @johnwilander


Komplett separation avinnehåll, kod ochformgivning möjliggörCSP.Monday, February 4, 13@joakimkemeny & @johnwilander


Men våra legacywebbarär en gröt.Monday, February 4, 13@joakimkemeny & @johnwilander


iframeJavaScriptCSSHTMLHantera legacywebboch tredjepartswebbi iframes. Då kan nykod köra med CSP.CSSHTMLJavaScriptJavaScriptHTMLCSSMonday, February 4, 13@joakimkemeny & @johnwilander


main.1-liner.orgSandboxed iframemain.1-liner.org CSS… eller …3rdparty.netJavaScript HTMLSätt sen sandboxdirektivetutanallow-sameoriginoch låtsame-origin policyCSSHTMLJavaScriptskydda er nya kodJavaScriptHTMLCSSfrån gröt ochsårbarheter.Monday, February 4, 13@joakimkemeny & @johnwilander


main.1-liner.orgEtt alternativ somiframelegacy.1-liner.orgCSSär bakåtkompatibeltär attflytta legacy-kodJavaScriptHTMLtill en annanCSSHTMLJavaScriptsubdomän vilketockså gerJavaScriptHTMLCSSseparation mhasame-origin policy.Monday, February 4, 13@joakimkemeny & @johnwilander


new.1-liner.orgiframemain.1-liner.orgCSSJavaScript HTMLCSS HTMLJavaScriptHTMLJavaScriptCSSEn varning dock.Legacy-kod klararoftast intedomänändringar.Så ni kan få lov attändra subdomänför er nya kod.Monday, February 4, 13@joakimkemeny & @johnwilander


postMessagemain.1-liner.orgAnvändpostMessage-API:et för attSandboxed iframemain.1-liner.org CSS… or …3rdparty.netJavaScript HTMLkommuniceramellan iframes ochhuvidfönstret.CSSHTMLJavaScriptJavaScriptHTMLCSSMonday, February 4, 13@joakimkemeny & @johnwilander


postMessagemain.1-liner.orgSandboxed iframemain.1-liner.org CSS… or …3rdparty.netJavaScript HTMLCSS HTMLJavaScriptCORS from/to3rdparty.netSlutligen, använd CORS närJavaScriptni hämtar innehåll frånHTMLCSStredje part och se till attteckenkoda det innan nilägger till det i DOM:en.Monday, February 4, 13@joakimkemeny & @johnwilander


Sandboxed iframes17+22+4.2+10+5.1+No2.2+Rykten om att detsupportMonday, February 4, 13trots allt saknashttp://caniuse.com/#feat=iframe-sandbox@joakimkemeny & @johnwilander


Sandboxed iframemain.1-liner.orgMonday, February 4, 13@joakimkemeny & @johnwilander


Sandboxed iframemain.1-liner.orgMonday, February 4, 13@joakimkemeny & @johnwilander


Sandboxed iframemain.1-liner.orgMonday, February 4, 13@joakimkemeny & @johnwilander


Sandboxed iframemain.1-liner.orgMonday, February 4, 13@joakimkemeny & @johnwilander


DEMO SandboxediframeMonday, February 4, 13@joakimkemeny & @johnwilander


Länkar• https://gi<strong>th</strong>ub.com/joakimkemeny/presentation.modernweb• http://yeoman.io• http://twitter.gi<strong>th</strong>ub.com/bootstrap• http://html5boilerplate.com• http://requirejs.org• http://backbonejs.org• http://underscorejs.orgMonday, February 4, 13@joakimkemeny & @johnwilander

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!