Agile Ajax

Tagged:  
Dilbert

Video: Essentials of the DOM and JavaScript in 10 Minutes

Tagged:  

A screencast of a workshop on the DOM and JavaScript explaining the elements of the DOM and how to script it in JavaScript

With the increased use of Ajax, more developers have been exposed to the DOM. And whether you're new to JavaScript, or just need a refresher, this quick 10 minute video will touch on some fundamentals of DOM manipulation in JavaScript.

[youtube=http://www.youtube.com/watch?v=URF2sVQWuxU]

A GMail-like "Loading" Notifier

Tagged:  

This one is an oldie, but it's a goodie.

Ajax apps do stuff behind the scenes, so as developers we need to make a diligent effort to keep users notified with the current status of their requests. One of the quickest and easiest ways is to display a loading message whenever an process is running in the background. We've all seen GMail's Loading message on the top right corner of our screens when we're searching for mail and you can easily add that same functionality to your apps using the code from Point Writer.

Click here to check it out and try out the demo.

YSlow? aka Y(!Fast)

Tagged:  

YSlow analyzes web pages and tells you why they're slow based on the rules for high performance web sites. YSlow is a Firefox add-on integrated with the popular Firebug web development tool.

YSlow gives you:
* Performance report card
* HTTP/HTML summary
* List of components in the page
* Tools including JSLint

Podcast, Screencast
Take a look at the YSlow Podcast and Screencast.

Performance View
YSlow analyzes any web page and generates a grade for each rule and an overall grade. If a page can be improved, YSlow lists the specific changes to be made.

Stats View
YSlow calculates the total size of the web page for both empty cache and primed cache scenarios, as well as information about cookies.

Components View
YSlow lists all the components in the page including their type, URL, Expires date, gzip status, load time, size, and ETag. You can also view the HTTP response headers for any component.

Click here to visit the YSlow page at the Yahoo Developer Network

The Development Process

Tagged:  

If you need a good laugh, click the image below.

The Development Process

Take it one step further and make your own version of the comic!
Check out projectcartoon.com and create your own version by rearranging the slides and editing the captions.

Selenium: A testing tool for web apps

Tagged:  

Selenium is a test tool for web applications. Selenium tests run directly in a browser, just as real users do. And they run in Internet Explorer, Mozilla and Firefox on Windows, Linux, and Macintosh. This tool is great for testing your Ajax based applications because it can simulate user activity and assert results to ensure your code is executing as expected.

Browser compatibility testing. Test your application to see if it works correctly on different browsers and operating systems. The same script can run on any Selenium platform.

System functional testing. Create regression tests to verify application functionality and user acceptance.

Selenium IDE

Selenium IDE is an integrated development environment for Selenium tests. It is implemented as a Firefox extension, and allows you to record, edit, and debug tests. Selenium IDE includes the entire Selenium Core, allowing you to easily and quickly record and play back tests in the actual environment that they will run.
Selenium IDE is not only recording tool: it is a complete IDE. You can choose to use its recording capability, or you may edit your scripts by hand. With autocomplete support and the ability to move commands around quickly, Selenium IDE is the ideal environment for creating Selenium tests no matter what style of tests you prefer.

Features:

  • Easy record and playback
  • Intelligent field selection will use IDs, names, or XPath as needed
  • Autocomplete for all common Selenium commands
  • Walk through tests
  • Debug and set breakpoints
  • Save tests as HTML, Ruby scripts, or any other format
  • Support for Selenium user-extensions.js file
  • Option to automatically assert the title of every page

Click here to visit the Selenium homepage
and click here for the Selenium IDE

Optimize your Ajax with TIBCO General Interface Performance Profiler

Tagged:  

TIBCO General Interface Performance Profiler

As the complexity of your Ajax applications increase, so do the opportunities for performance issues to arise. Checkout TIBCO General Interface Performance Profiler, an open source (BSD License) Ajax application profiling tool for benchmarking the performance of Ajax solutions created with TIBCO General Interface and other Ajax toolkits. Create performance testing scripts in JavaScript then run them against live applications to get performance statistics for selected operations within your application. The Performance Profiler is smart enough to let you handle asynchronous operations too.

With this profiler, you can now dissect your application to test how long it takes your services to respond, your components to render, your data to parse, and your functions to execute. Basically everything you need to pinpoint the bottlenecks in your code. One thing this profiler won't do -- optimize your code for you -- that's your job.

Click here to vist Tibco's GI Performance Profiler Homepage

What Does Ajax Mean?

With a blog name like Ajaxonomy I would imagine that most users already have a definition of Ajax. Most of you already know that the term Ajax was coined by Jesse James Garrett and the term stands for Asynchronous JavaScript And XML. The method used to accomplish the Asynchronous (the main thing to remember regarding this is that it makes it so you don't need to refresh the page with every request) retrieval of the data is the JavaScript XMLHttpRequest object.

Below is an example of a simple JavaScript object for making an Ajax connection (Please note that there are quite a few great libraries that have similar code that may be a better fit for your application).

//Ajax Object Code
var net=new Object();
net.READY_STATE_UNINITIALIZED=0;
net.READY_STATE_LOADING=1;
net.READY_STATE_LOADED=2;
net.READY_STATE_INTERACTIVE=3;
net.READY_STATE_COMPLETE=4;
net.ContentLoader=function(url, onload, onerror, callingobject){
	this.url=url;
	this.req=null;
	this.callingobject=callingobject;
	this.onload=onload;
	this.onerror=(onerror) ? onerror : this.defaultError;
	this.loadXMLDoc(url);
};
net.ContentLoader.prototype={
	loadXMLDoc:function(url){
	        if(window.XMLHttpRequest){
	                this.req=new XMLHttpRequest();
	                if (this.req.overrideMimeType) {
          			 this.req.overrideMimeType('text/xml');
		        }
	        } else if (window.ActiveXObject){
	                try {
           			this.req=new ActiveXObject("Msxml2.XMLHTTP");
			} catch (err) {
				try {
					this.req=new ActiveXObject("Microsoft.XMLHTTP");
			} catch (err) {}
			}
	        }
	        if(this.req){
	                try{
				var loader=this;
	                        this.req.onreadystatechange=function(){
	                                loader.onReadyState.call(loader);
	                        };
	                        var TimeStamp = new Date().getTime();//This fixes a cache problem
	                        if(url.indexOf("?")<0){
		                        this.req.open('GET', url+"?timestamp="+TimeStamp, true);
	                        }else{
	                                this.req.open('GET', url+"×tamp="+TimeStamp, true);
	                        }
	                        this.req.send(null);
	                } catch (err){
	                        this.onerror.call(this);
	                }
	        }
	},
	onReadyState:function(){
	        var req=this.req;
	        var ready=req.readyState;
	        if(ready==net.READY_STATE_COMPLETE){
	                var httpStatus=req.status;
	                if(httpStatus==200||httpStatus===0){
	                        this.onload.call(this);
	                } else {
	                        this.onerror.call(this);
	                }
	        }
	},
	defaultError:function(){
	        alert("error fetching data!" + "\n\nreadyState: "+this.req.readyState + "\nstatus: "+this.req.status+"\nheaders: "+this.req.getAllResponseHeaders());
	}
};

I have found that there are three main interpretations on the meaning of Ajax.

  1. Asynchronously retrieval of data through the JavaScript XMLHttpRequest object which is always XML
  2. Asynchronously retrieval of data through the JavaScript XMLHttpRequest object which can be XML or JSON
  3. Asynchronously retrieval of data through the JavaScript XMLHttpRequest object which can be XML, JSON, HTML or any text string

Since Jesse James Garrett coined the term we should see what he says about the above. According to the question and answer section of Jesse's essay (click here to read the essay) Jesse appears to side on the latter two of the above meanings.

I personally like the last definition as it allows for me to be more flexible in designing my applications. Because of this whenever you hear me refer to Ajax I will be referring to the last definition. I know that you probably have a definition that you like and I would love to hear your favorites, so leave your favorite definition in the comments.

Google Ajax Feed API + Flickr Photo Feed + Mootools Image Reflection

Introduction
So this all started because I decided to play around with the Google Ajax Feed API, integrate it with the Flickr public photo feed, and add a Mootools Image Reflection script in to the mix to spice things up a bit.

Let's start with the Google Ajax Feed API and what it offers. With the AJAX Feed API, you can download any public Atom or RSS feed using only JavaScript, so you can easily mash up feeds with your content and other APIs like the Google Maps API. If you haven't had a chance to dig into it, you should. It's relatively simple and straightforward, is very quick to set up, and runs like a champ. First, you'll need to sign your site up for a API Key here.

Now let's take a look at the Flickr Photo Feed. Flickr is one of the biggest online photo management and sharing application in the world. They offer a free full blown API, but for this project I only used their public photo feed.

Finally, the third ingredient in this melting pot is an image reflection script based on the Mootools framework. Image reflection has become much more common in the Web 2.0 design style. This script provides a code based solution to creating reflections as opposed to hand creating them in an image editor like Adobe Photoshop. If you're not sure what I mean by image reflections, stay tuned for a quick and dirty demo.

Google Ajax Feed API
To begin using the Ajax API in a page, you first need to include the javascript code from google's server in your header, passing it your API key:

<script type=\"text/javascript\" src=\"http://www.google.com/jsapi?key=[your api key here]\"></script>

Next, initialize the API by calling

google.load("feeds", "1");

Specify your callback function by calling google.setOnLoadCallback(initialize); where initialize is the name of our callback function.


Finally, let's build the initialize function, to process the Flickr public feed after the API is ready.

function initialize() {      
	// this random number is used to guarantee we aren't getting a cached copy of the feed, which by default is in JSON format
	var randomnumber=Math.floor(Math.random()*1000000);
	
	// the flickr feed url is used to instantiate a new google feed object
	var feed = new google.feeds.Feed("http://api.flickr.com/services/feeds/photos_public.gne?rand="+randomnumber);

	// The container is a DIV that contains all the photos retrieved from Flickr
	// Each time this method is called, we need to erase the previous photos
	// with a little DOM manipulation
	var container = document.getElementById("feed");
	if(container != null){
		container.parentNode.removeChild(container);				
	}
	container = document.createElement("DIV");
	container.id = "feed";
	container.innerHTML = "<p class=\'loading\'>Loading...</p>";
	document.body.appendChild(container);

	// setNumEntries allows us to specify the number of elements Google will return
	// in the feed, the default is 4
	feed.setNumEntries(20);

	// we execute the load method to tell the api to fetch our feed
	// and we pass it our callback function
	feed.load(function(result) {
            if (!result.error) {               
	  // this removes our loading message
	  container.innerHTML = "";

	  // we loop through our result set (a JSON object)
              for (var i = 0; i < result.feed.entries.length; i++) {
	       // for each entry, we create a div, assign it a css class name,
	       // create a hyperlink back to the Flickr page contain the fullsize picture
	       // and create an image node for our thumnail
                   var entry = result.feed.entries[i];			
                   var div = document.createElement("div");
                   div.className = "imageDIV";			
                   var linkNode = document.createElement("a");
                   linkNode.href = entry.link;
                   linkNode.target = "_blank";				
                   var imageNode = document.createElement("img");
                   imageNode.id = "image"+i;
	       // parseImgURL is a method I wrote to parse out the thumbnail url from a node in
	       // in the JSON object since that contained other content
                   imageNode.src = parseImgURL(entry.content);
                   imageNode.border = 0;

	       // add the hyperlink to the image	, assign it to the div, and put it on the page
                   linkNode.appendChild(imageNode);		
                   div.appendChild(linkNode);
                   container.appendChild(div);

	       // finally, this one-liner is all we need to activate the reflection
	       // feature on the image we just added to the page. The first parameter
	       // in the add method is the image id, the second parameter is used for options
	       // like the height and opacity of the reflection. 
	       // .8 results in a reflection that is 80% of the height of the original image
                   Reflection.add('image'+i, {height:.8});
              }


            }
          });
}

Flickr Photo Feed
More information on the Flickr API can be found on their website.
For this project, I chose to only use their public feed (which doesn't require an API key).

Mootools Image Reflection
This script works in all browsers supporting the canvas tag: Firefox since version 1.5, Camino, Opera since version 9 and Safari since version 1.3. It also works in Internet Explorer 5.5 and more recent by using an alternative drawing technique.

Take a look at the Demo

Sources
Google Ajax Feed API: http://code.google.com/apis/ajaxfeeds/
Flickr Photo Feed: http://www.flickr.com/services/feeds/docs/photos_public/
Mootools Image Reflection Script: http://www.digitalia.be/software/reflectionjs-for-mootools

Protecting Your Application from SQL Injection.

As you probably know one common practice in server side coding is to pass variables directly into a query. This is perhaps most prevalent in PHP development (I love PHP, but most developers just pass the values right into the query). This leaves applications wide open to SQL injection attacks. This problem is only compounded with an Ajax application as crackers can simply look at your JavaScript to find out what URLs to use to attack. This can get worse as you may not even realize that you have been attacked if somebody just uses SQL injection to steal data (something that is getting much more common).

So, how are we to protect ourselves from such attacks? The first rule is to never trust any information that is sent from the user. If the value is supposed to be a number check to make sure it is a number or if it is supposed to be under a certain number of characters make sure it is under that number of characters. When checking user data never rely on client side checks as these can easily be bypassed.

The next thing you should do is change your server error settings. Often detailed error pages are used to gain information that helps an attacker get into your system. Change the error screens to be very generic, besides users don't need to know any more information regarding the error.

Once you fix the error screens and validate data you can use some string manipulation to convert certain characters (such as the semicolon, quotation marks and single quote) to web friendly characters (This is somewhat less important in the Java world as a JDBC connection handles much of these security issues automatically). One trick I've used is to convert a string to be URL encoded thus removing bad characters as well as all spaces. Of course you will need to remember to convert the string back to be displayed properly.

So, the main things to remember when protecting your application from SQL Injection are:

  1. Never trust data sent from your users
  2. Don't give away too much information in your error messages
  3. Check and clean the data of characters that are potentially threatening

For more information on protecting against SQL injection attacks click here.

I would love to hear how you are securing your applications from this huge threat, so leave comments on any tips or struggles that you have had.

Syndicate content