How to use Cross domain Ajax request

6

"How to use Cross domain Ajax request" by CMSN Software Tutorials, shows you how to perform cross domain Ajax request using jQuery. In this tutorial we are not trying to describe the other technologies available for Ajax request. If you are interesting about the ways of performing Ajax request please follow our previous post related to Ajax request. Here we are trying to explain why cross domain Ajax request is not allowed and how to overcome that issue.

Why cross domain Ajax request is not allowed
It is because of the Same origin policy. Same origin policy is an important security concept for a number of client side programming languages, such as JavaScript. You can access any page any script within the same site. But prevent access to the method and properties from different sites.
How to use Cross domain Ajax request
There are several way to perform this task. but here we are talking about only JSONP and the Server side proxy.
Following sample show you the way of consuming the JSONP enabled web service. The only difference is you have to pass the callback method with the Ajax request.
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="CrossDomainRequest.aspx.cs"
    Inherits="CMSNSoftwareTutorials.HowToUseCrossDomainAjaxRequest.JsonpSample.CrossDomainRequest" %>
 
<!DOCTYPE html>
<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>
    <script type="text/javascript" src=" https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
</head>
<body>
    <form id="form1" runat="server">
    <div class="car-details">
    </div>
    </form>
    <script type="text/javascript">
        $.ajax({
            url: 'http://localhost:7148/CarDetails.asmx/AllCars',
            type: 'GET',
            data: "{}",
            contentType: "application/json; charset=utf-8",
            dataType: "jsonp",
            jsonp: "callback",
            jsonpCallback: "jsonpCallbackfunction",
            error: function () {
                alert("Error in Jsonp");
            }
        });
 
        function jsonpCallbackfunction(responseData) {
            var dataReturnFromServer = responseData.d;
            var i = 0;
            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++;
            }
        }
    </script>
</body>
</html>

When you send the Ajax request using jQuery, Content type should be "application/json; charset=utf-8" and dataType should be "jsonp". Value of the jsonp option is used as a parameter name for callback function.Callback function should be set to jsonpCallback option. So final request is like url?callback=jsonpCallbackfunction. Response from the JSONP service is like jsonpCallbackfunction({...}). It is calling jsonpCallbackfunction() function with the response as parameter for it.

Following sample show you how to use server side proxy for call cross domain web service.
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="CrossDomainRequest.aspx.cs"
    Inherits="CMSNSoftwareTutorials.HowToUseCrossDomainAjaxRequest.ServerSideProxySample.CrossDomainRequest" %>
 
<!DOCTYPE html>
<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>
    <script type="text/javascript" src=" https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
</head>
<body>
    <form id="form1" runat="server">
    <div class="car-details">
    </div>
    </form>
    <script type="text/javascript">
        $.ajax({
            url: '/ServersideCrossDomainProxy.asmx/AllCars',
            type: 'GET',
            data: "{}",
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            success: ajaxSuccessfunction,
            error: function (jqXHR, textStatus, errorThrown) {
                alert(jqXHR.status + " : " + errorThrown);
            }
        });
 
        function ajaxSuccessfunction(responseData) {
            var dataReturnFromServer = responseData.d;
            var i = 0;
            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++;
            }
        }
    </script>
</body>
</html>

This is normal Ajax request to the web service hosted in the same site.Content type should be "application/json; charset=utf-8" and dataType should be "json".

//-----------------------------------------------------------------------
// <copyright file="ServerSideCrossDomainProxy.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.HowToUseCrossDomainAjaxRequest.ServerSideProxySample
{
    using System.Collections.Generic;
    using System.Linq;
    using System.Web.Script.Services;
    using System.Web.Services;
    using CMSNSoftwareTutorials.HowToUseCrossDomainAjaxRequest.ServerSideProxySample.CrossDomainService;
 
    /// <summary>
    /// Server side Proxy for support cross domain request.
    /// </summary>
    [WebService(Namespace = "http://cmsnsoftware.blogspot.com/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    [System.Web.Script.Services.ScriptService]
    public class ServerSideCrossDomainProxy : System.Web.Services.WebService
    {
        /// <summary>
        /// details of all cars.
        /// </summary>
        /// <returns>details of all cars</returns>
        [WebMethod]
        [ScriptMethod(UseHttpGet = true, ResponseFormat = ResponseFormat.Json)]
        public List<Car> AllCars()
        {
            CarDetails carDetails = new CarDetails();
            return carDetails.AllCars().ToList<Car>();
        }
    }
}

This is an intermediate web service to call cross domain web service in the server side. In this web service we call the other site web service by adding reference to it. If you dont know how to add web service reference to project, please follow MSDN preference here.

Following sample show you how to configure Asp.net web service to support JSONP response. Usually Asp.net web service return result as xml. But if you pass the content type as "application/json; charset=utf-8" it will return the JSON response. But for the JSONP formatted response should like jsonpCallbackfunction({...}). You can simply wrap the response with the callback function name. In the asp.net 2.0 it is working fine. but from the asp.net 3.5 onwards the entire response is wrapped within a new "d" object.{"d":{"jsonpCallbackfunction({...})"}}. Because of this we need to find a workaround for this. The easiest way is write a custom HTTP module and wrap the response using the module.
//-----------------------------------------------------------------------
// <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.HowToUseCrossDomainAjaxRequest.CrossDomainWebService
{
    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 List<Car> AllCars()
        {
            return PopulateCarDetails();
        }
 
        /// <summary>
        /// Populates the car details.
        /// </summary>
        /// <returns>car details</returns>
        private static List<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="JsonpModule.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.HowToUseCrossDomainAjaxRequest.CrossDomainWebService
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
 
    /// <summary>
    /// Custom Http module for support Jsonp response
    /// </summary>
    public class JsonpModule : IHttpModule
    {
        /// <summary>
        /// callback Parameter Name for Jsonp request
        /// </summary>
        private const string CallbackParameterName = "callback";
 
        /// <summary>
        /// Initializes a module and prepares it to handle requests.
        /// </summary>
        /// <param name="context">An <see cref="T:System.Web.HttpApplication"/> that provides access to the methods, properties, and events common to all application objects within an ASP.NET application</param>
        public void Init(HttpApplication context)
        {
            context.BeginRequest += new EventHandler(this.Application_BeginRequest);
            context.EndRequest += new EventHandler(this.Application_EndRequest);
        }
 
        /// <summary>
        /// Disposes of the resources (other than memory) used by the module that implements <see cref="T:System.Web.IHttpModule"/>.
        /// </summary>
        public void Dispose()
        {
        }
 
        /// <summary>
        /// Handles the BeginRequest event of the Application 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>
        private void Application_BeginRequest(object sender, EventArgs e)
        {
            HttpApplication httpApplication = (HttpApplication)sender;
 
            ////Make sure only apply to Jsonp requests
            if (!string.IsNullOrEmpty(httpApplication.Context.Request.Params[CallbackParameterName]))
            {
                if (string.IsNullOrEmpty(httpApplication.Context.Request.ContentType))
                {
                    httpApplication.Context.Request.ContentType = "application/json; charset=utf-8";
                }
 
                httpApplication.Context.Response.Write(httpApplication.Context.Request.Params[CallbackParameterName] + "(");
            }
        }
 
        /// <summary>
        /// Handles the EndRequest event of the Application 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>
        private void Application_EndRequest(object sender, EventArgs e)
        {
            HttpApplication httpApplication = (HttpApplication)sender;
            if (!string.IsNullOrEmpty(httpApplication.Context.Request.Params[CallbackParameterName]))
            {
                httpApplication.Context.Response.Write(")");
            }
        }
    }
}

This module automatically converts the response to JSONP format. But we have wrote it to support JSONP and the as well as normal web service response. If you pass the callback parameter to the web service this module wrap the response with the callback function. If you want to be more specific, you can check for the web service name as well.

//-----------------------------------------------------------------------
// <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.HowToUseCrossDomainAjaxRequest.CrossDomainWebService
{
    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.

<?xml version="1.0"?>
 
<!--
  For more information on how to configure your ASP.NET application, please visit
  http://go.microsoft.com/fwlink/?LinkId=169433
  -->
 
<configuration>
  <system.web>
    <compilation debug="true" targetFramework="4.0" />
    <webServices>
      <protocols>
        <add name="HttpGet"/>
        <add name="HttpPost"/>
      </protocols>
    </webServices>
    <httpModules>
      <add name="JSONAsmx" type="CMSNSoftwareTutorials.HowToUseCrossDomainAjaxRequest.CrossDomainWebService.JsonpModule"/>
    </httpModules>
  </system.web>
 
</configuration>

Your web.config file should like this.

Download tutorial

6 comments:

Anonymous -
Hi would you mind stating which blog platform you're using?
I'm looking to start my own blog soon but I'm having a tough time
deciding between BlogEngine/Wordpress/B2evolution and Drupal.
The reason I ask is because your layout seems different then most blogs and I'm looking for
something completely unique. P.S My apologies for being off-topic but I had to ask!


Here is my blog post promotional codes for Halfords
Chamika Sandamal -
Here we are using Blogger(blogspot.com) as the blog platform. You can always change the layout the way you want in blogger. so don't limit to the existing templates and just create your own template and upload it to the blogger.

Post a Comment