How to create SEO friendly AJAX applications

0

"How to create SEO friendly AJAX applications" by CMSN Software Tutorials, shows you how to configure your Ajax applications to support search engine optimization. In this tutorial we are not going to describe about the Hijax but about the Google new proposal for ajax applications. Earlier Ajax applications have been difficult for search engines to process because AJAX content is produced dynamically by the browser and thus not visible to crawlers.

Following sample shows you how to use the crawler friendly Ajax urls. Normally in the Ajax applications we are using hash fragments for keep the state of application. we are using the same concept here. But instead of using #key=value we have to use #!key=value. And in the server side we have to accept those parameters. But problem is url hash fragment cannot read in the server side. Google solution for this is, use _escaped_fragment_=key1=value1.crawler will automatically bind these urls bidirectional.
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="AjaxSample.aspx.cs" Inherits="CMSNSoftwareTutorials.SeoFriendlyAjaxApplications.AjaxSample" %>
 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <style type="text/css">
        .car-information
        {
            display-webkit-box;
            -webkit-box-orienthorizontal;
            -webkit-box-alignstretch;
            display-moz-box;
            -moz-box-orienthorizontal;
            -moz-box-alignstretch;
            display-o-box;
            -o-box-orienthorizontal;
            -o-box-alignstretch;
            displaybox;
            box-orienthorizontal;
            box-alignstretch;
            margin5px 0 0;
            width100%;
        }
        .car-information div
        {
            -webkit-box-flex1;
            -moz-box-flex1;
            box-flex1;
            width720px;
            padding0 5px;
            text-alignjustify;
            border-bottom1px solid #C2D6FF;
        }
        .car-information:hover
        {
            background-color#C2D6FF;
        }
    </style>
</head>
<body>
    <form id="form1" runat="server">
    <button class="car-details-button" type="button">
        Load Car Details</button>
    <asp:Literal runat="server" ID="CarDetails">
    <div class="car-details">
    </div>
    </asp:Literal>
    </form>
    <script type="text/javascript" src=" https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
    <script type="text/javascript">
        function loadCarDetails() {
            $.ajax({
                url: '/CarDetails.asmx/AllCars',
                type: 'GET',
                data: "{}",
                contentType: "application/json; charset=utf-8",
                dataType: "json",
                success: ajaxSuccessfunction,
                error: function (jqXHR, textStatus, errorThrown) {
                    alert(jqXHR.status + " : " + errorThrown);
                }
            });
        }
        $(".car-details-button").click(function () {
            window.location.hash = "!allCars";
        });
        function ajaxSuccessfunction(responseData) {
            var dataReturnFromServer = responseData.d;
            var i = 0;
            $(".car-details").empty();
            while (dataReturnFromServer.length > i) {
                $(".car-details").append(function () {
                    var carInformation = $("<div/>", { "class""car-information" }).append($("<div/>").html(dataReturnFromServer[i].Make))
                    .append($("<div/>").html(dataReturnFromServer[i].Model)).append($("<div/>").html(dataReturnFromServer[i].Year))
                    .append($("<div/>").html(dataReturnFromServer[i].Doors)).append($("<div/>").html(dataReturnFromServer[i].Color))
                    .append($("<div/>").html(dataReturnFromServer[i].Price));
                    return carInformation;
                });
                i++;
            }
        }
 
        // call init
        $(init);
        function init() {
            ajax_page_handler();
            page_load($(window.location).attr("hash")); // goto first page if #!: is available
        }
 
        function page_load($href) {
            if ($href != undefined && $href.substring(0, 2) == '#!') {
                if ($href === "#!allCars") {
                    loadCarDetails();
                }
                $('html, body').animate({ scrollTop: 0 }, 'slow'); // bonus
            }
        }
 
        function ajax_page_handler() {
            $(window).bind('hashchange'function () {
                $href = $(window.location).attr("hash");
                page_load($href);
            });
        }
    </script>
</body>
</html>

we are binding custom function to hashchange event and just change the hash value when click on the button. for multiple parameters it should look like, _escaped_fragment_=key1=value1%26key2=value2

//-----------------------------------------------------------------------
// <copyright file="AjaxSample.aspx.cs" company="CMSN Software">
//    Copyright © 2012  CMSN Software
//    This program is free software: you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation, either version 3 of the License, or
//    (at your option) any later version.
//
//    This program is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//    GNU General Public License for more details.
//
//    You should have received a copy of the GNU General Public License
//    along with this program.  If not, see http://www.gnu.org/licenses.
// </copyright>
//-----------------------------------------------------------------------
namespace CMSNSoftwareTutorials.SeoFriendlyAjaxApplications
{
    using System;
    using System.Collections.Generic;
    using System.Text;
 
    /// <summary>
    /// generates same output of the ajax
    /// </summary>
    public partial class AjaxSample : System.Web.UI.Page
    {
        /// <summary>
        /// Handles the Load event of the Page control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        protected void Page_Load(object sender, EventArgs e)
        {
            string commad = Request.Params["_escaped_fragment_"];
            CarDetails cd = new CarDetails();
            switch (commad)
            {
                case "allcars":
                    CarDetails.Text = "<div class='car-details'>" + GetAllCarDetails(cd.AllCars()) + "</div>";
                    break;
                default:
                    break;
            }
        }
 
        /// <summary>
        /// Gets all car details.
        /// </summary>
        /// <param name="carList">The car list.</param>
        /// <returns>html output for all car details</returns>
        private static string GetAllCarDetails(IList<Car> carList)
        {
            StringBuilder carDetails = new StringBuilder();
            foreach (Car itm in carList)
            {
                carDetails.Append("<div class='car-information'>");
                carDetails.Append("<div>" + itm.Make + "</div>");
                carDetails.Append("<div>" + itm.Model + "</div>");
                carDetails.Append("<div>" + itm.Year + "</div>");
                carDetails.Append("<div>" + itm.Doors + "</div>");
                carDetails.Append("<div>" + itm.Color + "</div>");
                carDetails.Append("<div>" + itm.Price + "</div>");
                carDetails.Append("</div>");
            }
 
            return carDetails.ToString();
        }
    }
}

Here we need to read the QueryString value of _escaped_fragment_

Nothing new in following code. This is just a sample data providing web service to support the application.
//-----------------------------------------------------------------------
// <copyright file="CarDetails.asmx.cs" company="CMSN Software">
//    Copyright © 2010  CMSN Software
//    This program is free software: you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation, either version 3 of the License, or
//    (at your option) any later version.
//
//    This program is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//    GNU General Public License for more details.
//
//    You should have received a copy of the GNU General Public License
//    along with this program.  If not, see http://www.gnu.org/licenses.
// </copyright>
//-----------------------------------------------------------------------
        
namespace CMSNSoftwareTutorials.SeoFriendlyAjaxApplications
{
    using System.Collections.Generic;
    using System.Web.Script.Services;
    using System.Web.Services;
 
    /// <summary>
    /// Web service for car details
    /// </summary>
    [WebService(Namespace = "http://cmsnsoftware.blogspot.com/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    [System.Web.Script.Services.ScriptService]
    public class CarDetails : System.Web.Services.WebService
    {
        /// <summary>
        /// car details
        /// </summary>
        /// <returns>list of all car details</returns>
        [WebMethod]
        [ScriptMethod(UseHttpGet = true, ResponseFormat = ResponseFormat.Json)]
        public IList<Car> AllCars()
        {
            return PopulateCarDetails();
        }
 
        /// <summary>
        /// Populates the car details.
        /// </summary>
        /// <returns>car details</returns>
        private static IList<Car> PopulateCarDetails()
        {
            List<Car> cars = new List<Car>();
            cars.Add(new Car { Make = "Audi", Model = "A4", Year = 1995, Doors = 5, Color = "Red", Price = 2995f });
            cars.Add(new Car { Make = "Ford", Model = "Focus", Year = 2002, Doors = 5, Color = "Black", Price = 3250f });
            cars.Add(new Car { Make = "BMW", Model = "5 Series", Year = 2006, Doors = 4, Color = "Grey", Price = 24950f });
            cars.Add(new Car { Make = "Renault", Model = "Laguna", Year = 2000, Doors = 5, Color = "Red", Price = 3995f });
            cars.Add(new Car { Make = "Toyota", Model = "Previa", Year = 1998, Doors = 5, Color = "Green", Price = 2695f });
            cars.Add(new Car { Make = "Mini", Model = "Cooper", Year = 2005, Doors = 2, Color = "Grey", Price = 9850f });
            cars.Add(new Car { Make = "Mazda", Model = "MX 5", Year = 2003, Doors = 2, Color = "Silver", Price = 6995f });
            cars.Add(new Car { Make = "Ford", Model = "Fiesta", Year = 2004, Doors = 3, Color = "Red", Price = 3759f });
            cars.Add(new Car { Make = "Honda", Model = "Accord", Year = 1997, Doors = 4, Color = "Silver", Price = 1995f });
            return cars;
        }
    }
}

This is a simple web service witch returns list of custom type objects as the response. For the list object you don't need to serialize the response. Asp.net engine will automatically do it for you.

//-----------------------------------------------------------------------
// <copyright file="Car.cs" company="CMSN Software">
//    Copyright © 2010  CMSN Software
//    This program is free software: you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation, either version 3 of the License, or
//    (at your option) any later version.
//
//    This program is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//    GNU General Public License for more details.
//
//    You should have received a copy of the GNU General Public License
//    along with this program.  If not, see http://www.gnu.org/licenses.
// </copyright>
//-----------------------------------------------------------------------
        
namespace CMSNSoftwareTutorials.SeoFriendlyAjaxApplications
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
 
    /// <summary>
    /// keeps car information
    /// </summary>
    public class Car
    {
        /// <summary>
        /// Gets or sets the make.
        /// </summary>
        /// <value>
        /// The manufacture of the car.
        /// </value>
        public string Make { getset; }
 
        /// <summary>
        /// Gets or sets the model.
        /// </summary>
        /// <value>
        /// The model of the car.
        /// </value>
        public string Model { getset; }
 
        /// <summary>
        /// Gets or sets the year.
        /// </summary>
        /// <value>
        /// The year of the car.
        /// </value>
        public int Year { getset; }
 
        /// <summary>
        /// Gets or sets the doors.
        /// </summary>
        /// <value>
        /// number of doors of the car.
        /// </value>
        public int Doors { getset; }
 
        /// <summary>
        /// Gets or sets the color.
        /// </summary>
        /// <value>
        /// The color of the car.
        /// </value>
        public string Color { getset; }
 
        /// <summary>
        /// Gets or sets the price.
        /// </summary>
        /// <value>
        /// The price.
        /// </value>
        public float Price { getset; }
    }
}

This is a custom class to keep sample data.

Download tutorial

0 comments:

Post a Comment