Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / ASP.NET

Check if JavaScript is Enabled from Server-Side Using an User Control

4.59/5 (27 votes)
28 May 2008CPOL4 min read 2   2K  
An ASP.NET User Control which can check if Javascript is enabled in the user's browser, and either does postback to perform an alternate action from the server side, or redirects to a non-JavaScript page.

Introduction

This is an alternate design approach using an ASP.NET user control to determine if the users have either purposely or inadvertently disabled JavaScript on their browsers, and either submit the form to perform some actions from server-side or navigate to another non-JavaScript page.

Background

Most ASP.NET/AJAX/JavaScript developers must have faced this issue:

"How to check if JavaScript is enabled/disabled in the user's browser"

The answer is, you cannot, without doing a postback from the user's browser. Although .NET provides a way to verify browser support for JavaScript through the use of 'Request.Browser.JavaScript', it does not tell us if JavaScript is enabled. So, how do we test if the client has JavaScript enabled?

Fortunately, there are many answers on the Internet. Most techniques available on the Web use some form of the following: Use JavaScript to change a value in a form and then submit the form via JavaScript. After submitting, check the value and compare it to the original. If it has changed, then JavaScript is enabled. If it hasn't changed, then either JavaScript isn't supported or JavaScript isn't enabled.

However, the solutions I found on the Internet do not provide the following:

  • Reusability.
  • Integration with ASP.NET.
  • Most of them use JavaScript to postback to the same page, but sometimes, it is required to navigate to a non-JavaScript page if JavaScript is disabled, instead of displaying the same broken page.
  • Ability to include the control once on the master page and do the check in all the pages and user controls.

I wanted something more elegant. I had two choices, either a custom server control, or an ASP.NET user control. I came to the conclusion that the user control would be the best solution as it would be easy to customize and maintain.

Using the Code

As I have already mentioned, there is no way of checking if JavaScript is enabled from the server-side on the first request. So, if JavaScript is disabled, we have to do a postback, or redirect to a non JavaScript page, using:

HTML
<NOSCRIPT>
  <meta http-equiv=REFRESH content=0;URL={target url}>
</NOSCRIPT>

In the above code, the target URL can be the same page or any other non-JavaScript page.

CheckJS.ascx

ASP.NET
<%@ Control Language="C#" AutoEventWireup="true" 
            CodeFile="CheckJS.ascx.cs" Inherits="CheckJS" %>
<asp:HiddenField ID="hfClientJSEnabled" runat="server" Value="False" />

<script type="text/javascript">
    document.getElementById('<%= hfClientJSEnabled.ClientID %>').value = "True";
    if (document.getElementById('<%= hfClientJSEnabled.ClientID %>').value != 
                                '<%= IsJSEnabled %>')
    {        
        window.location.href= '<%= GetAppendedUrl(JSQRYPARAM, JSENABLED) %>';
    }

</script>

This is the code in the CheckJS.ascx page. This contains a hidden field and a JavaScript block.

IsJSEnabled is a boolean server-side control property which stores and retrieves the JavaScript enabled flag. As the name indicates, its value is true if JavaScript is enabled. The default value of this property is true.

If the user turns on the JavaScript while the page has already loaded, the above JavaScript will execute. The IsJSEnabled will return true.

JavaScript
if (document.getElementById('<%= hfClientJSEnabled.ClientID %>').value != 
                            '<%= IsJSEnabled %>')

This will cause the page to navigate to the URL returned by GetAppendedUrl.

CheckJS.ascx.cs

C#
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Collections.Specialized;
using System.Text;

public partial class CheckJS : System.Web.UI.UserControl
{
    protected static string JSQRYPARAM = "jse";
    protected static string JSENABLED = "1";
    protected static string JSDISABLED = "0";

    protected override void OnInit(EventArgs e)
    {
        base.OnInit(e);
        bool testJS = IsJSEnabled;
        if (Request.QueryString[JSQRYPARAM] != null)
        {
            IsJSEnabled = Request.QueryString[JSQRYPARAM] == JSENABLED;
        }
    }

    protected void Page_Load(object sender, EventArgs e)
    {

    }
    protected string GetAppendedUrl(string newParam, string newParamValue)
    {
        string targeturl = string.Empty;
        Uri url = (string.IsNullOrEmpty(ResolveUrl(NonJSTargetURL))) ? 
                    new Uri(ResolveUrl(JSTargetURL)) : 
                    new Uri(ResolveUrl(NonJSTargetURL));
        if (url == null)
            url = Request.Url;

        string[] qry = url.Query.Replace("?","").Split('&');

        StringBuilder sb = new StringBuilder();
        foreach (string s in qry)
        {
            if (!s.ToLower().Contains(newParam.ToLower()))
            {
                sb.Append(s + "&");
            }
        }

        if (sb.Length > 0)
        {
            sb.Remove(sb.Length - 1, 1);
            targeturl = string.Format("{0}?{1}&{2}={3}", 
                        url.AbsolutePath, sb.ToString(), newParam, newParamValue);
        }
        else
        {
            targeturl = string.Format("{0}?{1}={2}", 
                        url.AbsolutePath, newParam, newParamValue);
        }
        return targeturl;
    }
    protected override void OnPreRender(EventArgs e)
    {
        base.OnPreRender(e);
        if (IsJSEnabled)
        {
            string targeturl = GetAppendedUrl(JSQRYPARAM, JSDISABLED);
            HtmlGenericControl ctrl = new HtmlGenericControl("NOSCRIPT");
            ctrl.InnerHtml = string.Format("<meta http-equiv=REFRESH " + 
                             "content=0;URL={0}>", targeturl);
            Page.Header.Controls.Add(ctrl);
        }
        else
        {
            if (NonJSTargetURL != null)
                Response.Redirect(NonJSTargetURL);
            HtmlGenericControl ctrl = new HtmlGenericControl("NOSCRIPT");
            ctrl.InnerHtml = string.Empty;
            Page.Header.Controls.Add(ctrl);
        }
    }
    protected bool IsJSEnabled
    {
        get
        {
            if (Session["JS"] == null)
                Session["JS"] = true;

            return (bool)Session["JS"];
        }
        set
        {
            Session["JS"] = value;
        }
    }
    protected string JSTargetURL
    {
        get
        {
            return Request.Url.ToString();
        }
    }
    public string NonJSTargetURL
    {
        get
        {
            return (ViewState["NONJSURL"] != null) ? 
                    ViewState["NONJSURL"].ToString() : string.Empty;
        }
        set
        {
            try
            {
                ViewState["NONJSURL"] = ResolveServerUrl(value, false);
            }
            catch
            {
                throw new ApplicationException("Invalid URL. '" + value + "'");
            }
        }
    }
    public string ResolveServerUrl(string serverUrl, bool forceHttps)
    {
        if (serverUrl.IndexOf("://") > -1)

            return serverUrl;
        string newUrl = ResolveUrl(serverUrl);
        Uri originalUri = HttpContext.Current.Request.Url;

        newUrl = (forceHttps ? "https" : originalUri.Scheme) +
                 "://" + originalUri.Authority + newUrl;
        return newUrl;
    } 
}

This is the source code for the code-behind for the CheckJS user control.

  1. OnInit — Check the Request query string for the parameter "jse". Set the value of IsJSEnabled.
  2. NonJSTargetURL — This property is optional. This is the URL to a non-JavaScript page. If not specified, then it will do a submit to the same page.
  3. GetAppendedUrl — This returns the URL, appending the appropriate query string parameters for the JavaScript enabled flag. This method takes NonJSTargetURL into account for generating the URL.
  4. OnPreRender — Based on the IsJSEnabled flag, this method renders: <NOSCRIPT><meta http-equiv=REFRESH content=0;URL={target url}></NOSCRIPT>.

Please note that we do not have to do the redirect always. After the first request, the information about the user's browser is stored in the session variable until the user changes the settings in the browser.

How to Use the JSCheck User Control

It's really easy to use this user control.

Here are the steps:

  1. Download CheckJSEnabledUserControl.zip.
  2. Copy CheckJS.ascx and CheckJS.ascx.cs to your controls folder.
  3. Open your Master page and add this control to the page.
  4. Make sure this control is added to the page control hierarchy as high as possible. This is required because the initialization of the IsJSEnabled property is done in the OnInit method. So, to make sure that JSCheck's OnInit fires before any other control's OnInit, the JSCheck control should be on top of the control hierarchy as far as possible.
  5. Now, to check if JavaScript is enabled or disabled, call CheckJavaScriptHelper.IsJavascriptEnabled.
C#
public class CheckJavaScriptHelper
{
    public static bool IsJavascriptEnabled
    {
        get
        {
            if (HttpContext.Current.Session["JS"] == null)
                HttpContext.Current.Session["JS"] = true;
            return (bool)HttpContext.Current.Session["JS"];
        }
    }
}

CheckJavaScriptHelper is the helper class which can be used to check if JavaScript is enabled or disabled without actually referencing the control on each individual page or control.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)