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

JavaScript for Windows server side.

5.00/5 (2 votes)
27 Oct 2014CPOL7 min read 22K  
Using JavaScript in Windows shell and Windows Web server (IIS).

Introduction

Windows supports the JavaScript in the shell and web server without the need to install node.js or any other server-side JavaScript engine. This article contains the most first steps for creating JavaScript applications for MS Windows Shell and MS Windows web server (IIS). 

Background

Reasons to read the article:

Study on how to use MS JavaScript language on the server side in windows. Finally this enables to use one programming language for client side code (in-browser code) and server side code, which makes a great return when developing programs.

Part 1. JavaScript in Windows shell

Hello world

  - write the following code in the Notepad.exe and save it in the file hello.js:

JavaScript
var msg = 'Hello world!'; 
WScript.Echo(msg); 

- click the hello.js in the windows explorer. The message "Hello world!" appears. 

What is going on: 

When you click the script one of the following programs (that are called windows script host) is executed: 
CScript.exe or WScript.exe, and the hello.js is sent as an input parameter, e.g.: 

WScript.exe hello.js

The script host loads the content of the script and executes it. 
Inside the JavaScript code there is a call

JavaScript
WScript.Echo(msg);

This WScript is one of built-in modules that extends the JavaScript functionality in Windows operating systems. 

Why you may need the JavaScript without browser? 
Windows script host allows to write complex scenarios, such as file and text processing, database updates, service calls, automation and so on. 

 

JavaScript module

Let's write a module in JavaScript. 

JavaScript
var myModule = (function() { 
   //Private vars/methods 
   var msg = "Hello world!"; 

   var hello = function() { 
       WScript.Echo(msg); 
   } 

   //Public vars/methods 
   return { 
       hello: hello 
   } 
})(); 

myModule.hello(); 

 - save the text in the file module.js and click on it in the windows explorer.  The system will show you the "Hello world!" message. 

Why you need 7 rows of code instead of 2 ?

The modules make it easier to build complex and extendable applications. 
If the example above still looks unfamiliar for you, I suggest making a pause here and google about JavaScript module pattern. 

 

Debugging JavaSript in Windows.

The next sample is a bit more complex, so it is a good time to say about the JavaScript debugging in MS Windows. 

You can run the WScript (or CScript) with option //X. 
The system will run the script in debugger (if you have installed the Visual Studio Pro). 
Visual Studio supports run-bypass, step-over, step-into debugging (keys F5,F10,F11) 
With F5 (run-bypass) script will be executed to the end, unless the debugger meets the JavaScript directive "debugger". 

Steps:

- make sure you have installed Visual Studio Professional

- in the command shell run the following command

cscript hello.js //X

- in the pop-up window "Visual Studio just-in time debugger" select to debug your script with the the new instance of Visual Studio.

- hit F11 key to debug the script.

- highlith the variables. Left click it and from the drop-down menu select "Add Watch" or "QuickWatch"

 

The further explanation heavily depends on your ability to debug the script code, to find errors, to evaluate the run-time values in the scripts using the Visual Studio.

 

Calling external services

Let's write a module that calls the external service, reads the binary data, and saves them in the file, and then calls the windows shell to play this data. 

JavaScript
var helloController = (function() { 
   //Private vars/methods 
   var serviceURL = "http://translate.google.com/translate_tts?ie=UTF-8&tl=es&q=";; 
   var msg = "¡Hola%20Mundo!"; 
   var msgFile = "c:\\temp\\Gspeak.mp3"; 

   var hello = function() { 
       HttpDownload(serviceURL + msg, msgFile); 
   } 

   var HttpDownload = function(strURL, strDestLocation) { 
       var ObjXMLHTTP = WScript.CreateObject("Msxml2.XMLHTTP"); 
       objXMLHTTP.Open("GET", strURL, false); 
       objXMLHTTP.send() 
       if (objXMLHTTP.Status == 200) { 
           var objADOStream = WScript.CreateObject("ADODB.Stream"); 
           objADOStream.Open(); 
           objADOStream.Type = 1; // 1=adTypeBinary 
           objADOStream.Write(objXMLHTTP.responseBody); 
           objADOStream.position = 0;   //Set the stream position to the start 
           objADOStream.SaveToFile(strDestLocation, 2); //2=overwrite file 
           objADOStream.Close(); 
           var wS = WScript.CreateObject("WScript.Shell"); 
           wS.Run(strDestLocation); 
       } 
       else { 
           Wscript.Echo("Status not good:" + objXMLHTTP.Status); 
       } 
   } 

   //Public vars/methods 
   return { 
       hello: hello 
   } 
})(); 

helloController.hello(); 

Steps: 
- Save this code into the file voice.js 
- Create a new file debug.bat with the following text: 
   cscript voice.js //X 
- Click the debug.bat and debug the script in the Visual Studio clicking F11(step-into). 
- Find the error in the script and fix it. 

If you succeed, the script will call the Google translate service, send the message there, and download the generated voice mp3 file that corresponds to the message, and play it. 

(Please note that the Google may change the url. The actual url can be found on their page https://translate.google.com/ with firebug-like tools) 

 

Part 2. JavaScript in the Windows Web Server (IIS)

Now when we can create JavaScript programs for Windows on the server side, 
let's create the JavaScript program for IIS (IIS is a built-in web server of the all Windows operating systems). 
(Please note - the following steps are NOT intended for the hosted or production environment, but are for local development environment only. Any version of Windows will suffice, even XP SP2) 

Steps: 
 - make sure you have IIS up and running 
 - enable script debugging in the IIS 
 - enable ASP scripts (AKA Classic ASP) in the IIS 
 - in the root folder of the web server (typically c:\inetpub\wwwroot\) create a new file test.asp 

Why ".asp"? The reason is that we are going to use a built-in IIS scripting engine that supports JavaScript scenarios for web pages. 

 - open your test.asp in the Notepad and insert the following code 

 

JavaScript
<%@  language="javascript" %> 
<% 
 var msg = 'Hello world!'; 
 Response.Write(msg); 
%>

 - save the file 
 - open the browser and navigate to the page http://localhost/test.asp 

 

The system should show the message "Hello world!" 

What is going on here: 
When you open the URL your browser sends the GET request to server with this URL. 
IIS server locates the folder and file in the folder(in our case the folder in a a root folder) and loads the file into the scripting engine (note that if the IIS can't locate the folder or file, the error handler will be called for 404 Error. We will use this later for nice-formatted URLs). Scripting engine reads the code between pseudo-tags <% and %> and executes the found code. By default the VBScript is used as the scripting language. You can re-define the default scripting language with the IIS settings or with the directive 
<%@  language="javascript" %>, which should be the first instruction in the file. 

So after the script engine loads the file, the JavaScript code is executed. The variable msg takes the string value. Then the value of this variable is merged with the HTML content of the script file with Response.Write() call.  Since there is no HTML content in the script file, the only output is the "Hello world!" message. 

Read more about the built-in Response object here: 
http://www.w3schools.com/asp/asp_ref_response.asp 

Other built-in objects that we are going to use are here: 
http://www.w3schools.com/asp/ 

ASP Response 
ASP Request 
ASP Application 
ASP Session 
ASP Server 
ASP Error 

 

Debugging: 

Put the instruction debugger before the rows of code as shown below: 

JavaScript
<%@  language="javascript" %> 
<% 
 debugger; 
 var msg = 'Hello world!'; 
 Response.Write(msg); 
%> 

If you set up the IIS script debugging correctly, then your code will be executed in debug mode in the  Visual Studio.

 

Receiving GET values: 

Steps:

- replace the code in the test.asp with the following code: 

JavaScript
<%@  language="javascript" %> 
<% 
 var controller = Request.QueryString("c"); 
 var action = Request.QueryString("a"); 
  
 Response.Write("{controller:" + controller); 
 Response.Write(","); 
 Response.Write("action:" + action); 
 Response.Write("}"); 

  
%> 

- open your browser and navigate to the page http://localhost/test.asp?c=home&a=index 
- the IIS will show the page with the following content: 

  {controller:home,action:index} 


Read more about getting values from Request in Classic ASP here: 
http://www.w3schools.com/asp/coll_querystring.asp 

 

Structured code:

Let's modify the code above as following: 

JavaScript
<%@  language="javascript" %> 
<% 
   debugger; 

    var Controllers={}; 
    var homeController = (function() { 
       //Private vars/methods 
       var msg = "Hello world!"; 
       var hello = function() { 
           Response.Write(msg); 
       } 
       //Public vars/methods 
       return { 
           hello: hello 
       } 
    })(); 
     
    Controllers["homeController"] = homeController; 

    function route(){ 
        var controller = String(Request.QueryString("c")).toLowerCase() + "Controller"; 
        var action = String(Request.QueryString("a")).toLowerCase(); 
         
        if (typeof Controllers[controller]!="undefined") 
            if (typeof Controllers[controller][action]!="undefined") 
                if (typeof Controllers[controller][action]=="function"){ 
                    Controllers[controller][action](); 
                    return; 
        } 
        Response.Write('error 404. controller or action was not found'); 
    } 
   route(); 
%> 

Steps:

 - save the code 

 - open the browser and navigate to the URL 

http://localhost/test.asp?c=home&a=hello 

You should see the message "Hello world!"

What is important here: 

1. We created the single entry of the application - a function route(). 
When this function is called it routes the request (passes the execution) to the appropriate Controller and Action. There is only one Controller - a "homeController", which has one actions - "hello"  action in this sample; however you can extend the logic of your application. 
Actually, the MVC pattern is applied here to the code. 

If the purity of logic due to code separation have not convinced you to use this "unnecessary complication" of your code, please google more about the mvc architectural pattern. 

2. Array "Controllers" allows to restrict the code execution. If we don't restrict it then some malicious valid JavaScript may be executed. 

3. Local variables of the modules do NOT hold the values between requests. If you want to save something between two requests - use the database or session variables. 

 

Extend modules logic:

Let's extend the homeControler with some new actions as shown below: 

JavaScript
<%@  language="javascript" %> 
<% 
   debugger; 

    var Controllers={}; 

    var homeController = (function() { 
       //Private vars/methods 
        var msg = "Hello world!"; 
         
        var index = function() { 
           say("Welcome to my page"); 
        }; 
         
        var hello = function() { 
           say(msg); 
        }; 

        var sayhello = function() { 
           var name = String(Request.QueryString("name")); 
           if (name=="undefined") 
                 say("hello dude"); 
            else 
                say("hello " + name + "!"); 
        }; 

        var say = function(txtMsg) { 
           Response.Write(txtMsg); 
        }; 
         
       //Public vars/methods 
       return { 
           index: index, 
           hello: hello, 
           sayhello:sayhello 
       } 
    })(); 
     
    Controllers["homeController"] = homeController; 

    function route(){ 
        var controller = String(Request.QueryString("c")).toLowerCase() + "Controller"; 
        var action = String(Request.QueryString("a")).toLowerCase(); 
         
        if (typeof Controllers[controller]!="undefined") 
            if (typeof Controllers[controller][action]!="undefined") 
                if (typeof Controllers[controller][action]=="function"){ 
                    Controllers[controller][action](); 
                    return; 
        } 
         
        Response.Write('error 404. controller or action was not found'); 
       
    } 

route(); 
%> 

 Try to navigate the following links: 

http://localhost/test.asp?c=home&a=index 
http://localhost/test.asp?c=home&a=hello 
http://localhost/test.asp?c=home&a=sayhello&name=Emmet 

 

 

Add another controller:

JavaScript
<%@  language="javascript" %> 
<% 
   debugger; 

    var Controllers={}; 

    var homeController = (function() { 
       //Private vars/methods 
        var msg = "Hello world!"; 
         
        var index = function() { 
           say("Welcome to my page"); 
        }; 
         
        var hello = function() { 
           say(msg); 
        }; 

        var sayhello = function() { 
           var name = String(Request.QueryString("name")); 
           if (name=="undefined") {
                var token = String(Request.Cookies("token"));
                if (token!="")
                    say("I remember you! you are " + token)
                else
                    say("hi dude");
            } 
            else 
                say("hello " + name + "!"); 
        }; 

        var say = function(txtMsg) { 
           Response.Write(txtMsg); 
        }; 
         
       //Public vars/methods 
       return { 
           index: index, 
           hello: hello, 
           sayhello:sayhello 
       } 
    })(); 
     
    Controllers["homeController"] = homeController; 

    var securityController = (function() { 
       //Private vars/methods 
         
        var login = function() { 
            var token = Math.floor(Math.random()*1001); 
            Response.Cookies("token") = String(token); 
            Response.Write("{result:true,"); 
            Response.Write("token:" + String(token)); 
            Response.Write("}"); 
        }; 
         
        var logout = function() { 
            Response.Cookies("token") =""; 
            Response.Write("{result:true}"); 
        }; 

         
       //Public vars/methods 
       return { 
           login: login, 
           logout:logout 
       } 
    })(); 
     
    Controllers["securityController"] = securityController; 

    function route(){ 
        var controller = String(Request.QueryString("c")).toLowerCase() + "Controller"; 
        var action = String(Request.QueryString("a")).toLowerCase(); 
         
        if (typeof Controllers[controller]!="undefined") 
            if (typeof Controllers[controller][action]!="undefined") 
                if (typeof Controllers[controller][action]=="function"){ 
                    Controllers[controller][action](); 
                    return; 
        } 
         
        Response.Write('error 404. controller or action was not found'); 
       
    } 

route(); 
%> 

 

- Try it with the following URLs:

1 test case:

http://localhost/test5.asp?c=home&a=sayhello

 

2 test case:

http://localhost/test5.asp?c=security&a=login

http://localhost/test5.asp?c=home&a=sayhello

 

3 test case:

http://localhost/test5.asp?c=security&a=logout

http://localhost/test5.asp?c=home&a=sayhello

 

History

All samples are tested with Windows 2003, IIS 6. 

This article is created as an attempt to answer the questions of users jaked6803 and kangchoi. I'm sorry guys, not all the questions can be answered because there are so many things to explain.  There is a lack of simple tutorials on how to use JavaScript in Windows. I hope this effort will help to start using JavaScript in Windows and make it less painful.

License

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