{"id":169,"date":"2011-06-15T12:33:32","date_gmt":"2011-06-15T10:33:32","guid":{"rendered":"https:\/\/alistapart.com\/it\/article\/trucchi-e-suggerimenti-per-il-debugging-moderno\/"},"modified":"2011-06-15T12:33:32","modified_gmt":"2011-06-15T10:33:32","slug":"trucchi-e-suggerimenti-per-il-debugging-moderno","status":"publish","type":"article","link":"https:\/\/alistapart.com\/it\/article\/trucchi-e-suggerimenti-per-il-debugging-moderno\/","title":{"rendered":"Trucchi e suggerimenti per il debugging moderno"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/alistapart.com\/it\/wp-content\/uploads\/sites\/2\/2011\/06\/n29bug.jpg\" border=\"0\" width=\"254\" height=\"170\" align=\"left\" \/>Con l&#8217;aumentare dei dispositivi mobili, lo sviluppo ed il debugging web \u00e8 divenuto pi\u00f9 complesso che mai: dobbiamo supportare pi\u00f9 browser e pi\u00f9 piattaforme, ci sono molte pi\u00f9 dimensioni di schermo e risoluzioni e stiamo creando applicazioni all&#8217;interno del browser invece dei noiosi siti vetrina di un tempo.<\/p>\n<p>Fortunatamente, abbiamo anche a disposizione degli strumenti migliori. La console JavaScript \u00e8 una caratteristica standard per la maggior parte dei browser. Sia JavaScript che il DOM HTLM offrono nativamente l&#8217;error handling. Ci sono anche servizi ed applicazioni che ci aiutano a fare il debug da remoto dei nostri siti.<\/p>\n<p>In questo articolo tratter\u00f2 l&#8217;error thowing and handling, il code injection ed il debugging per mobile. Per maggiori informazioni sul debugging, si veda l&#8217;articolo del 2009 di Hallvord R.M. Steen e Chris Mills, <a href=\"http:\/\/www.alistapart.com\/articles\/advanced-debugging-with-javascript\/\">Advanced Debugging With JavaScript<\/a>.<\/p>\n<div class=\"paragrafo\">\n<h2>Error throwing and catching<\/h2>\n<p>JavaScript vi permette di tenere traccia e di gestire gli errori attraverso una combinazione di istruzioni <code>throw<\/code> e <code>try<\/code>\u2026<code>catch<\/code> e tramite l&#8217;oggetto <code>error<\/code>.<\/p>\n<p>L&#8217;error throwing \u00e8 utile per cogliere gli errori a runtime, come ad esempio, una funzione che ha gli argomenti sbagliati. Nell&#8217;esempio sottostante, <code>add()<\/code> accetta due parametri. Far\u00e0 il throw di un errore se gli argomenti che le vengono passati sono nulli o se non sono n\u00e9 un numero n\u00e9 una stringa numerica. [Gli \u201ca capo\u201d sono segnati con \u00bb, <em>\u2014Ed.<\/em>]<\/p>\n<pre> \nfunction add(x,y){\n     if( isNaN(x) || isNaN(y) ){\n          throw new Error(\"Hey, I need two numbers to add!\");\n     } else {\n\t      \/\/ ensure we're adding numbers not concatenating \u00bb\nnumeric strings.\n\t     return (x * 1) + (y * 1);\n     }\n}\n<\/pre>\n<p>Proviamo a richiamare <code>add()<\/code> usando degli argomenti non validi. Faremo il catch dell&#8217;errore \u201clanciato\u201d utilizzando un blocco <code>try<\/code>\u2026<code>catch<\/code> e lo manderemo in output sulla console:<\/p>\n<pre> \nvar a;\n \ntry{\n a = add(9);\n} catch(e) {\n console.error( e.message );\n}\n<\/pre>\n<div class=\"illustration full left\"><img decoding=\"async\" src=\"http:\/\/alistapart.com\/it\/wp-content\/uploads\/sites\/2\/2011\/06\/catching_errors_dfl.png\" border=\"0\" alt=\"La error console di Dragonfly\" \/><\/p>\n<p>Fig 1: La error console di Dragonfly<\/p>\n<\/div>\n<p>In Dragonfly di Opera (illustrato qui sopra), possiamo vedere il messaggio di errore ed il corrispondente numero di riga, relativo allo script. Tenete sempre a mente che in questi esempi stiamo inserendo il JavaScript nella nostra pagina HTML.<\/p>\n<div class=\"illustration full left\"><img decoding=\"async\" src=\"http:\/\/alistapart.com\/it\/wp-content\/uploads\/sites\/2\/2011\/06\/catching_errors_fb.png\" border=\"0\" alt=\"La error console di Firebug.\" \/><\/p>\n<p>Fig. 2: La error console di Firebug<\/p>\n<\/div>\n<p>Firebug include anche il messaggio dell&#8217;errore lanciato ed il numero di riga, ma relativamente al documento.<\/p>\n<p>Tutti gli oggetti error hanno tre propriet\u00e0 standard:<\/p>\n<ul>\n<li><code>constructor<\/code>: ritorna un riferimento alla funzione Error che ha creato il prototipo dell&#8217;istanza,<\/li>\n<li><code>message<\/code>: il messaggio lanciato, il messaggio che passate come argomento,<\/li>\n<li><code>name<\/code>: il tipo di errore, solitamente <code>error<\/code>, a meno di usare un <a href=\"http:\/\/es5.github.com\/#x15.11.1\">tipo pi\u00f9 specifico<\/a>.<\/li>\n<\/ul>\n<p>Al momento in cui scrivo, gli oggetti error in Firefox includono anche due propriet\u00e0 non standard: <code>fileName<\/code> e <code>lineNumber<\/code>. Internet Explorer include due propriet\u00e0 non standard proprietarie: <code>description<\/code> (che funziona in maniera simile a <code>message<\/code>) e <code>number<\/code> (che d\u00e0 in output il numero di linea).<\/p>\n<p>Anche la propriet\u00e0 <code>stack<\/code> non \u00e8 standard, ma \u00e8 pi\u00f9 o meno supportata dalle versioni pi\u00f9 recenti di Chrome, Firefox e Opera. Traccia l&#8217;ordine delle chiamate di funzione, con i corrispondenti numeri di linea ed argomenti. Modifichiamo il nostro esempio per allertare <code>stack<\/code> invece:<\/p>\n<pre> \nvar a;\n \ntry{\n a = add(9);\n} catch(e) {\n alert( e.stack );\n}\n<\/pre>\n<div class=\"illustration full left\"><img decoding=\"async\" src=\"http:\/\/alistapart.com\/it\/wp-content\/uploads\/sites\/2\/2011\/06\/opera_stack_trace.png\" border=\"0\" \/><\/p>\n<p>Fig 3: La propriet\u00e0 stack rivela il \u201cthrow error\u201d nel codice.<\/p>\n<\/div>\n<p>La propriet\u00e0 <code>stack<\/code> rivela il punto in cui \u00e8 presente il codice <code>throw Error<\/code> (in questo caso, alla riga 7) e su quale riga l&#8217;errore \u00e8 stato fatto scattare (in questo caso, la riga 15).<\/p>\n<p>Non dovete per forza lanciare (throw) un oggetto error. Potreste, ad esempio, lanciare un messaggio: <code>throw \"The value of x or y is NaN.\"<\/code>. Lanciare un errore, tuttavia, d\u00e0 maggiori informazioni nella maggior parte dei browser.<\/p>\n<p>Utilizzare <code>try<\/code>\u2026<code>catch<\/code> pu\u00f2 comunque avere un effetto negativo sulla riduzione della dimensione del codice e sulla performance. Sebbene sia comodo per il debugging, il vostro codice pronto per andare in produzione dovrebbe utilizzare <code>try<\/code>\u2026<code>catch<\/code> in maniera molto limitata, se non addirittura evitarlo.<\/p>\n<\/div>\n<div class=\"paragrafo\">\n<h2>Gestione degli errori con l&#8217;evento <code>window.onerror<\/code><\/h2>\n<p>Anche il Document Object Model offre un meccanismo per catturare gli errori: l&#8217;evento <code>window.onerror<\/code>. A differenza di <code>try<\/code>\u2026<code>catch<\/code>, potete impostare un gestore di eventi per <code>window.onerror<\/code> che catturi gli errori che voi <em>non<\/em> lanciate. Questo accade se cercate di invocare una funzione non definita o se provate ad accedere ad una variabile indefinita.<\/p>\n<p>Quando viene attivato l&#8217;evento <code>window.onerror<\/code>, il browser far\u00e0 un controllo per vedere se c&#8217;\u00e8 disponibile una funzione handler. Se non ve ne sono, il browser mostrer\u00e0 l&#8217;errore all&#8217;utente. Se invece ce n&#8217;\u00e8 una disponibile, la funzione handler riceve tre argomenti:<\/p>\n<ul>\n<li>il messaggio di errore,<\/li>\n<li>l&#8217;URL nel quale \u00e8 stato sollevato l&#8217;errore e<\/li>\n<li>il numero di riga dove si \u00e8 verificato l&#8217;errore.<\/li>\n<\/ul>\n<p>Si pu\u00f2 accedere a questi argomenti in uno dei due modi seguenti:<\/p>\n<ol>\n<li>utilizzando l&#8217;oggetto <code>arguments<\/code> che \u00e8 nativo e localmente disponibile per tutte le funzioni JavaScript, oppure<\/li>\n<li>utilizzando dei <a href=\"http:\/\/en.wikipedia.org\/wiki\/Named_parameter\">named parameters<\/a>.<\/li>\n<\/ol>\n<p>Nell&#8217;esempio seguente, useremo <code>arguments<\/code>. Tuttavia, per favorire la leggibilit\u00e0, dovreste utilizzare i named parameters:<\/p>\n<pre> \n \nwindow.onerror = function(){\n alert(arguments[0] +'\\n'+arguments[1]+'\\n'+arguments[2]);\n}\n \ninit(); \/\/ undefined and triggers error event.\n<\/pre>\n<div class=\"illustration full left\"><img decoding=\"async\" src=\"http:\/\/alistapart.com\/it\/wp-content\/uploads\/sites\/2\/2011\/06\/onerror_ie.png\" border=\"0\" alt=\"Il nostro errore appare come un alert in Internet Explorer 9\" \/><\/p>\n<p>Fig 4: Il nostro errore appare come un alert in Internet Explorer 9<\/p>\n<\/div>\n<p>Qui <code>init()<\/code> non \u00e8 stato ancora definito. come risultato, l&#8217;evento <code>onerror<\/code> verr\u00e0 attivato nei browser che lo supportano.<\/p>\n<p>Avvertimento: il supporto per <code>window.onerror<\/code> \u00e8 limitato. Chrome 10+ e Firefox (inclusa la versione mobile) lo supportano. Internet Explorer lo supporta, ma i messaggi d&#8217;errore veramente utili si trovano solo dalla versione 9+. Sebbene gli ultimi build di WebKit supportino <code>window.onerror<\/code>, le versioni recenti di Safari e le versioni leggermente pi\u00f9 vecchie di Android WebKit non lo supportano. Anche Opera non lo supporta perfettamente. Aspettatevi che le cose cambino man mano che la specifica di HTML5 si evolve ed i produttori di browser adeguano di conseguenza le loro implementazioni.<\/p>\n<\/div>\n<div class=\"paragrafo\">\n<h2>Modificare JavaScript al volo usando l&#8217;interfaccia a riga di comando<\/h2>\n<p>Una delle caratteristiche pi\u00f9 potenti disponibile ad oggi nei tool per il debug \u00e8 la console JavaScript. E&#8217; praticamente una riga di comando (CLI) per JavaScript. Con essa potete fare il dump dei dati o inserire del JavaScript per esaminare il motivo per cui il codice si comporta in maniera inaspettata.<\/p>\n<h3>Lanciare la Console JavaScript<\/h3>\n<ul>\n<li>In <strong>Chrome<\/strong>: View &gt; Developer &gt; JavaScript console<\/li>\n<li>In <strong>Safari<\/strong>: Develop &gt; Show Web Inspector<\/li>\n<li>In <strong>Internet Explorer 8 &amp; 9<\/strong>: Tools &gt; Developer Tools (oppure utilizzare il tasto F12)<\/li>\n<li>In <strong>Opera<\/strong>: Cercate Dragonfly in Tools &gt; Advanced (Mac OS X) o Menu &gt; Page &gt; Developer Tools (Windows, Linux)<\/li>\n<\/ul>\n<p><strong>Firefox<\/strong> \u00e8 un caso speciale. Per anni, gli sviluppatori hanno utilizzato l&#8217;estensione <a href=\"http:\/\/getfirebug.com\">Firebug<\/a>. Tuttavia, Firefox 4 ha aggiunto una console nativa (Tools &gt; Web Console oppure Menu &gt; Web Developer &gt; Web Console).<\/p>\n<p>Firebug supporta completamente le <a href=\"http:\/\/getfirebug.com\/wiki\/index.php\/Console_API\">Console API<\/a> e ha delle caratteristiche di debugging CSS pi\u00f9 robuste. Suggerisco di installarlo, sebbene la Web Console sia un tool adatto alle necessit\u00e0 di base.<\/p>\n<p>Negli esempi qui sotto utilizzo il tool di debug di Opera, <a href=\"http:\/\/opera.com\/dragonfly\/\">Dragonfly<\/a> (ebbene s\u00ec, lavoro per Opera). Questi esempi, comunque, funzionano in maniera simile in Chrome, Safari, Firefox, Firebug e Internet Explorer.<\/p>\n<p>Diamo un&#8217;altra occhiata al codice dei nostri esempi precedenti. Aggiungiamo una nuova riga \u2014<code>var a = document.querySelector('#result');<\/code>\u2014, che assume un elemento con il valore dell&#8217;id impostato in \u201cresult.\u201d<\/p>\n<p>Rapida nota riguardante il metodo <code>querySelector()<\/code>: questo e <code>querySelectorAll()<\/code> fanno parte delle <a href=\"http:\/\/www.w3.org\/TR\/selectors-api\/\">selectors API<\/a> del <abbr title=\"Document Object Model\">DOM<\/abbr>. <code>querySelector()<\/code> ritorna il primo elemento uguale al <a href=\"http:\/\/www.w3.org\/TR\/css3-selectors\/\"> selettore <abbr title=\"Cascading Style Sheets\">CSS<\/abbr><\/a>. Entrambe i metodi sono supportati dalle ultime versioni della maggior parte dei browser. Potreste anche usare <code>document.getElementById('result')<\/code>, ma <code>document.querySelector()<\/code> \u00e8 pi\u00f9 efficiente:<\/p>\n<pre> \nfunction add(x,y){\n if( isNaN(x) || isNaN(y) ){\n     throw new Error(\"Hey, I need two numbers to add!\");\n } else {\n     \/\/ ensure we're adding numbers not concatenating numeric strings.\n     return (x * 1) + (y * 1);\n }\n}\n \nvar a = document.getElementById('result');\n \ntry{\n     a.innerHTML = add(9);\n} catch(e) {\n     console.error(e.message);\n}\n<\/pre>\n<div class=\"illustration full left\"><img decoding=\"async\" src=\"http:\/\/alistapart.com\/it\/wp-content\/uploads\/sites\/2\/2011\/06\/console_dragonfly.png\" border=\"0\" alt=\"La console Dragonfly\" \/><\/p>\n<p>Fig 5: La console Dragonfly<\/p>\n<\/div>\n<p>L&#8217;errore che abbiamo lanciato \u00e8 scritto ancora nella console. Ma introduciamo del JavaScript che funziona correttamente. Inseriremo <code>a.innerHTML = add(21.2, 40);<\/code> nella nostra console:<\/p>\n<div class=\"illustration full left\"><img decoding=\"async\" src=\"http:\/\/alistapart.com\/it\/wp-content\/uploads\/sites\/2\/2011\/06\/console_dragonfly_injected_code_con.png\" border=\"0\" alt=\"La console Dragonfly con il codice introdotto\" \/><\/p>\n<p>Fig 6: La console Dragonfly con il codice introdotto<\/p>\n<\/div>\n<p>Come potete vedere, abbiamo sovrascritto il valore <code>innerHTML<\/code> di <code>a<\/code>:<\/p>\n<div class=\"illustration full left\"><img decoding=\"async\" src=\"http:\/\/alistapart.com\/it\/wp-content\/uploads\/sites\/2\/2011\/06\/console_dragonfly_injected_code.png\" border=\"0\" alt=\"Una pagina con il codice introdotto\" \/><\/p>\n<p>Fig 7: Una pagina con il codice introdotto<\/p>\n<\/div>\n<p>Adesso cambiamo completamente il valore di <code>a<\/code>. Inseriamo <code>a = document.querySelector('h1'); a.innerHTML = add(45,2);<\/code> nella console:<\/p>\n<div class=\"illustration full left\"><img decoding=\"async\" src=\"http:\/\/alistapart.com\/it\/wp-content\/uploads\/sites\/2\/2011\/06\/console_dragonfly_injected_code2.png\" border=\"0\" alt=\"Cambiamo il codice nella console\" \/><\/p>\n<p>Fig 8: Cambiamo il codice nella console<\/p>\n<\/div>\n<p>Vedete che 47 viene scritto nella console ed \u00e8 anche il nuovo <code>innerHTML<\/code> del nostro elemento <code>h1<\/code>:<\/p>\n<div class=\"illustration full left\"><img decoding=\"async\" src=\"http:\/\/alistapart.com\/it\/wp-content\/uploads\/sites\/2\/2011\/06\/console_dragonfly_injected_code3.png\" border=\"0\" alt=\"Modificare il DOM\" \/><\/p>\n<p>Fig 9: Modificare il DOM<\/p>\n<\/div>\n<p>Ora, possiamo perfino ridefinire la nostra funzione <code>add()<\/code>. Facciamo in modo che <code>add()<\/code> ritorni il prodotto di due argomenti e poi aggiorni l&#8217;elemento <code>h1<\/code>. Inseriamo <code>function add(){ return arguments[0] * arguments[1]; }<\/code> nella console, seguito da <code>a.innerHTML = add(9,9);<\/code>:<\/p>\n<div class=\"illustration full left\"><img decoding=\"async\" src=\"http:\/\/alistapart.com\/it\/wp-content\/uploads\/sites\/2\/2011\/06\/console_dragonfly_injected_code4.png\" border=\"0\" alt=\"Sovrascrivere una funzione con la console JavaScript\" \/><\/p>\n<p>Fig 10: Sovrascrivere una funzione con la console JavaScript<\/p>\n<\/div>\n<p>Il nuovo <code>innerHTML<\/code> del nostro elemento <code>h1<\/code> \u00e8 adesso 81, ossia il risultato della nostra funzione <code>add<\/code> ridefinita:<\/p>\n<div class=\"illustration full left\"><img decoding=\"async\" src=\"http:\/\/alistapart.com\/it\/wp-content\/uploads\/sites\/2\/2011\/06\/console_dragonfly_injected_code5.png\" border=\"0\" alt=\"I risultati della sovrascrittura di una funzione\" \/><\/p>\n<p>Fig 11: I risultati della sovrascrittura di una funzione<\/p>\n<\/div>\n<p>La console JavaScript offre un potente tool per la comprensione del funzionamento del nostro codice. E&#8217; ancora pi\u00f9 potente quando la si usa con i dispositivi mobili.<\/p>\n<\/div>\n<div class=\"paragrafo\">\n<h2>Debugging da remoto per mobile<\/h2>\n<p>Il debug del codice su un dispositivo mobile \u00e8 ancora uno dei punti pi\u00f9 dolenti. Ma, ancora una volta, adesso abbiamo dei tool. Dragonfly di Opera e la sua feature per il debug remoto fornisce agli sviluppatori un modo per debuggare i siti mobile dalla propria postazione desktop. Recentemente, WebKit <a href=\"http:\/\/www.webkit.org\/blog\/1620\/webkit-remote-debugging\/\">ha aggiunto il remote debugging<\/a> al suo core e Google Chrome l&#8217;ha gi\u00e0 inserito nei suoi developer tool.<\/p>\n<p>Gli sviluppatori indipendenti offrono prodotti simili per altri browser. Tra questi citiamo <a href=\"http:\/\/bugabooapp.com\/\">Bugaboo<\/a>, una app iOS per il debug basata su Safari, <a href=\"http:\/\/jsconsole.com\/\">JS Console<\/a> che \u00e8 disponibile sul web o come app iOS e <a href=\"http:\/\/pmuellr.github.com\/weinre\/\">Weinre<\/a> per i browser basati su WebKit.<\/p>\n<p>Esaminiamone due: <strong>Dragonfly remote debug<\/strong> e <strong>JSConsole<\/strong>.<\/p>\n<h3>Remote debugging con Opera Dragonfly<\/h3>\n<p>Il punto di forza di Dragonfly \u00e8 che vi si pu\u00f2 fare il debug dei CSS o degli header (si veda il Network tab) oltre che di JavaScript. Per\u00f2 richiede l&#8217;installazione di Opera sul proprio desktop e di <a href=\"http:\/\/www.opera.com\/mobile\/\">Opera Mobile<\/a> sul proprio device.<\/p>\n<p>Entrambe i device devono poi essere connessi alla stessa rete locale. Vi servir\u00e0 anche l&#8217;indirizzo IP della macchina su cui \u00e8 in esecuzione Dragonfly. Poi completate i seguenti passi:<\/p>\n<ol>\n<li>aprite Dragonfly dal menu Tools &gt; Advanced (Mac OS X) o Page &gt; Developer Tools (Windows, Linux),<\/li>\n<li>cliccate il pulsante Remote Debug <img decoding=\"async\" src=\"http:\/\/alistapart.com\/it\/wp-content\/uploads\/sites\/2\/2011\/06\/remote_debug_btn.png\" border=\"0\" alt=\"The Remote Debugger button\" \/>,<\/li>\n<li>se volete potete modificare il numero della porta o utilizzare quella di default e cliccare su \u201cApply, \u201d\n<div class=\"illustration full left\"><img decoding=\"async\" src=\"http:\/\/alistapart.com\/it\/wp-content\/uploads\/sites\/2\/2011\/06\/remote_debugging_dragonfly.png\" border=\"0\" alt=\"Il pannello di remote debugging in Dragonfly\" \/><\/p>\n<p>Fig 12: Il pannello di remote debugging in Dragonfly<\/p>\n<\/div>\n<\/li>\n<li>aprite Opera Mobile sul device su cui volete fare il debug e scrivete <code>opera:debug<\/code> nella barra degli indirizzi\n<div class=\"illustration full left\"><img decoding=\"async\" src=\"http:\/\/alistapart.com\/it\/wp-content\/uploads\/sites\/2\/2011\/06\/remote_debugger_ondevice.png\" border=\"0\" alt=\"la debug console di Opera Mobile\" width=\"270\" \/><\/p>\n<p>Fig 13: La debug console di Opera Mobile<\/p>\n<\/div>\n<\/li>\n<li>inserite l&#8217;indirizzo IP ed il numero di porta della macchina host e cliccate su \u201cConnect\u201d\n<div class=\"illustration full left\"><img decoding=\"async\" src=\"http:\/\/alistapart.com\/it\/wp-content\/uploads\/sites\/2\/2011\/06\/dragonfly_ip.png\" border=\"0\" alt=\"I campi IP e Port della console opera:debug\" \/><\/p>\n<p>Fig 14: I campi IP e Port della console opera:debug<\/p>\n<\/div>\n<\/li>\n<li>puntate all&#8217;URL della pagina HTML che volete debuggare sul vostro device.<\/li>\n<\/ol>\n<div class=\"illustration right half\"><img decoding=\"async\" src=\"http:\/\/alistapart.com\/it\/wp-content\/uploads\/sites\/2\/2011\/06\/remote_debug_opera.png\" border=\"0\" alt=\"Un'alert su Opera Mobile\" \/><\/p>\n<p>Fig 15: Un&#8217;alert su Opera Mobile<\/p>\n<\/div>\n<p>Dragonfly sulla macchina host caricher\u00e0 la pagina remota. Potrete quindi interagire con la pagina come se fosse sul vostro desktop. Vedrete i risultati sul device. Ad esempio, se inserite <code>alert( add(8,923) )<\/code> sulla console host, l&#8217;alert appare sullo schermo del device mobile.<\/p>\n<h3>Remote debugging con JSConsole<\/h3>\n<p><a>JSConsole<\/a> \u00e8 un servizio web-based e browser-independent. A differenza di Bugaboo, Weinre e Dragonfly, il vostro computer ed il vostro device non devono essere connessi alla stessa rete locale.<\/p>\n<p>Per usare JSConsole:<\/p>\n<ul>\n<li>visitate il sito ed inserite <code>:listen<\/code> nel prompt,<\/li>\n<li>aggiungete al documento che volete debuggare il tag che ritorna lo script,<\/li>\n<li>aprite il documento sul vostro device mobile.<\/li>\n<\/ul>\n<p>Le istruzioni sulla console remota appariranno nella finestra di JSConsole (dovete usare <code>console.log()<\/code> piuttosto che <code>console.error()<\/code> o <code>console.warn()<\/code>). Potete anche inviare il codice dalla finestra JSConsole al vostro device. In questo caso, <code>alert( add(6,3) );<\/code>.<\/p>\n<div class=\"illustration full left\"><img decoding=\"async\" src=\"http:\/\/alistapart.com\/it\/wp-content\/uploads\/sites\/2\/2011\/06\/jsconsole.png\" border=\"0\" alt=\"Invio di un comando utilizzando JSConsole.com\" \/><\/p>\n<p>Fig 16: Invio di un comando utilizzando JSConsole.com<\/p>\n<\/div>\n<\/div>\n<div class=\"paragrafo\">\n<h2>Remote error logging<\/h2>\n<p>Nell&#8217;esempio di cui sopra, abbiamo fatto il tracciamento sulla console o abbiamo lanciato un&#8217;alert box. Cosa succederebbe se invece avessimo tracciato gli errori su uno script server-side?<\/p>\n<p>Considerate il seguente codice che utilizza <code>XMLHttpRequest()<\/code>.<\/p>\n<pre> \nfunction sendError(){\n     var o, xhr, data, msg = {}, argtype = typeof( arguments[0] );\n \n     \/\/ if it is an error object, just use it.\n     if( argtype === 'object' ){\n     \t  msg = arguments[0];\n     }\n \n     \/\/ if it is a string, check whether we have 3 arguments...\n     else if( argtype === 'string') {\n     \/\/ if we have 3 arguments, assume this is an onerror event.\n          if( arguments.length == 3 ){\n              msg.message    = arguments[0];\n              msg.fileName   = arguments[1];\n              msg.lineNumber = arguments[2];\n          }\n        \/\/ otherwise, post the first argument\n          else {\n              msg.message    = arguments[0];\n          }\n      }\n \n     \/\/ include the user agent\n     msg.userAgent = navigator.userAgent;\n \n\t \/\/ convert to JSON string\n\t data = 'error='+JSON.stringify(msg);\n \n     \/\/ build the XHR request\n     xhr = new XMLHttpRequest();\n     xhr.open(\"POST\",'.\/logger\/');\n     xhr.setRequestHeader(\"Content-type\", \"application\/x-www- \u00bb\n     form-urlencoded\");\n     xhr.send( data );\n \n \n     \/\/ hide error message from user in supporting browsers\n     return true;\n}\n<\/pre>\n<p>Qui stiamo postando i nostri messaggi di errore su uno script che li logga in un file utilizzando PHP:<\/p>\n<pre> \n&lt;?php\n \n\/\/ decode the JSON object.\n$error = json_decode( $_POST['error'], true );\n$file = fopen('log.txt','a');\nfwrite($file, print_r( $error, true) );\nfclose($file);\n \n?&gt;\n<\/pre>\n<p>E adesso il disclaimer: per favore, per l&#8217;amore della tequila, <em>non permettete allo script di scrivere su una directory che sia leggibile da tutti<\/em>. Non vale la pena correre il rischio di un potenziale attacco tramite code injection dovuto agli spoofed headers o alle variabili. Il tracciamento di script come questo dovrebbe essere usato soltanto durante lo sviluppo e mai sui server di produzione.<\/p>\n<h3>Conclusione<\/h3>\n<p>I tool a nostra disposizione si sono evoluti di pari passo con il web. Il code injection, l&#8217;error throwing and catching ed i servizi di remote debugging hanno tutti contribuito a farci distribuire app migliori e con meno errori.<\/p>\n<p>Illustrazioni: {carlok}<\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Essere sicuri che il nostro sito funzioni come ci si aspetta nei diversi browser e sui vari dispositivi pu\u00f2 essere una sfida anche per il pi\u00f9 esperto web developer. Seguite Tiffany B. Brown mentre spiega l&#8217;error thowing and handling, il code injection ed il mobile debugging utilizzando JavaScript.<\/p>\n","protected":false},"author":818,"featured_media":7000618,"comment_status":"open","ping_status":"open","template":"","categories":[271,43,278],"tags":[],"coauthors":[331],"class_list":["post-169","article","type-article","status-publish","has-post-thumbnail","hentry","category-javascript","category-numero-29-15-giugno-2011","category-workflow-tools"],"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/article\/169","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/article"}],"about":[{"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/types\/article"}],"author":[{"embeddable":true,"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/users\/818"}],"replies":[{"embeddable":true,"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/comments?post=169"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/media\/7000618"}],"wp:attachment":[{"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/media?parent=169"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/categories?post=169"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/tags?post=169"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/coauthors?post=169"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}