Click here to Skip to main content
15,867,141 members
Articles / Web Development / ASP.NET
Article

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

Rate me:
Please Sign up or sign in to vote.
4.59/5 (27 votes)
28 May 2008CPOL4 min read 170.1K   2K   39   25
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)


Written By
Architect
United States United States
I have more than 9 years of experience in various Microsoft Technologies. I spend most of my working time in C#, ASP.NET, WCF, WPF, WF and LINQ.

Check My Profile


Comments and Discussions

 
BugXSS vulnerability Pin
stuartmclean23-Jan-18 0:19
stuartmclean23-Jan-18 0:19 
Questiondoes not work Pin
Uthman Rahimi29-Oct-14 21:08
professionalUthman Rahimi29-Oct-14 21:08 
QuestionCondition gets failed even though JavaScript has been disabled in browser Pin
subhakarj17-May-14 2:27
subhakarj17-May-14 2:27 
Questionproblem in jse=1 Pin
naa3er17-Aug-12 23:52
naa3er17-Aug-12 23:52 
Question5 for the article Pin
Uday P.Singh18-Nov-11 9:07
Uday P.Singh18-Nov-11 9:07 
GeneralMy vote of 5 Pin
Abinash Bishoyi14-Nov-11 5:55
Abinash Bishoyi14-Nov-11 5:55 
QuestionMy vote of 4 Pin
Abinash Bishoyi14-Nov-11 5:52
Abinash Bishoyi14-Nov-11 5:52 
GeneralMy vote of 1 Pin
mitja.GTI8-Sep-10 6:25
mitja.GTI8-Sep-10 6:25 
GeneralMinor issue ... Pin
Chris Wolcott10-Jun-10 7:04
Chris Wolcott10-Jun-10 7:04 
GeneralNot W3C XHTML compliant Pin
banshiman2g1-May-10 11:21
banshiman2g1-May-10 11:21 
GeneralDoesn't work in Chrome Pin
h16h2-Apr-10 3:03
h16h2-Apr-10 3:03 
GeneralRe: Doesn't work in Chrome Pin
marshy6710-May-10 4:49
marshy6710-May-10 4:49 
GeneralMy vote of 1 Pin
Daniel 2k912-Mar-10 21:44
Daniel 2k912-Mar-10 21:44 
GeneralRe: My vote of 1 Pin
h16h2-Apr-10 3:05
h16h2-Apr-10 3:05 
QuestionIs there a Java server side check as well ? Pin
Member 45504718-Sep-09 23:00
Member 45504718-Sep-09 23:00 
QuestionNonJSTargetURL Pin
dolatta27-Jul-09 5:13
dolatta27-Jul-09 5:13 
GeneralLabel1 does not exist in the current context error. Pin
Kevin McGarrity2-Jun-09 0:08
Kevin McGarrity2-Jun-09 0:08 
GeneralRe: Label1 does not exist in the current context error. Pin
Kevin McGarrity2-Jun-09 0:52
Kevin McGarrity2-Jun-09 0:52 
QuestionAlways getting IsJSEnabled = true Pin
solidcode20016-Sep-08 3:26
solidcode20016-Sep-08 3:26 
AnswerRe: Always getting IsJSEnabled = true Pin
coverdale2-Apr-09 16:56
coverdale2-Apr-09 16:56 
NewsA little change Pin
jmpv3-Sep-08 6:02
jmpv3-Sep-08 6:02 
GeneralCongratulations! Pin
jmpv3-Sep-08 5:50
jmpv3-Sep-08 5:50 
GeneralWorks great! Pin
binabic11-Aug-08 20:12
binabic11-Aug-08 20:12 
GeneralTestApplication don't run on .NET 2.0 [modified] Pin
binabic11-Aug-08 1:42
binabic11-Aug-08 1:42 
AnswerRe: TestApplication don't run on .NET 2.0 Pin
coverdale2-Apr-09 16:52
coverdale2-Apr-09 16:52 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.