65.9K
CodeProject 正在变化。 阅读更多。
Home

适用于 Windows 服务器端的 JavaScript。

starIconstarIconstarIconstarIconstarIcon

5.00/5 (2投票s)

2014年10月27日

CPOL

7分钟阅读

viewsIcon

22583

在 Windows Shell 和 Windows Web 服务器 (IIS) 中使用 JavaScript。

引言

Windows 无需安装 node.js 或任何其他服务器端 JavaScript 引擎即可支持 Shell 和 Web 服务器中的 JavaScript。本文包含了为 MS Windows Shell 和 MS Windows Web 服务器 (IIS) 创建 JavaScript 应用程序的最初步步骤。 

背景

阅读本文的原因

研究如何在 Windows 服务器端使用 MS JavaScript 语言。最终,这使得可以使用一种编程语言处理客户端代码(浏览器内代码)和服务器端代码,这在开发程序时能带来巨大的回报。

第一部分:Windows Shell 中的 JavaScript

Hello world

 - 在 Notepad.exe 中写入以下代码,并将其保存为 hello.js 文件

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

- 在 Windows 资源管理器中单击 hello.js。将出现“Hello world!”消息。 

发生了什么: 

当您单击脚本时,将执行以下程序之一(称为 Windows Script Host): 
CScript.exe 或 WScript.exe,并将 hello.js 作为输入参数发送,例如: 

    WScript.exe hello.js 

脚本宿主加载脚本内容并执行它。 
在 JavaScript 代码内部有一个调用

WScript.Echo(msg);

此 WScript 是扩展 Windows 操作系统中 JavaScript 功能的内置模块之一。 

为什么您可能需要在浏览器外使用 JavaScript? 
Windows Script Host 允许编写复杂的场景,例如文件和文本处理、数据库更新、服务调用、自动化等。 

 

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(); 

 - 将文本保存到 module.js 文件中,并在 Windows 资源管理器中单击它。 系统将显示“Hello world!”消息。 

为什么需要 7 行代码而不是 2 行?

模块可以更轻松地构建复杂且可扩展的应用程序。 
如果上面的示例对您来说仍然不熟悉,我建议您在此暂停,并在网上搜索 JavaScript 模块模式。 

 

调试 Windows 中的 JavaScript。

下一个示例稍微复杂一些,所以这是一个介绍 MS Windows 中 JavaScript 调试的好时机。 

您可以使用 //X 选项运行 WScript(或 CScript)。 
系统将在调试器中运行脚本(如果您已安装 Visual Studio Pro)。 
Visual Studio 支持运行-绕过、逐过程、逐语句调试(按键 F5、F10、F11)。 
使用 F5(运行-绕过)脚本将一直执行到结束,除非调试器遇到 JavaScript 指令“debugger”。 

步骤

- 确保您已安装 Visual Studio Professional

- 在命令提示符中运行以下命令

     cscript hello.js //X 

- 在弹出窗口“Visual Studio Just-In-Time Debugger”中,选择使用新实例的 Visual Studio 调试您的脚本。 

- 按 F11 键调试脚本。 

- 高亮显示变量。左键单击它,然后从下拉菜单中选择“Add Watch”或“QuickWatch”。 

 

后续的解释很大程度上取决于您调试脚本代码、查找错误、使用 Visual Studio 评估脚本中运行时值的能力。 

 

调用外部服务

让我们编写一个调用外部服务、读取二进制数据并将其保存到文件,然后调用 Windows Shell 播放这些数据的模块。 

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(); 

步骤: 
- 将此代码保存到 voice.js 文件中。 
- 创建一个名为 debug.bat 的新文件,其中包含以下文本: 
   cscript voice.js //X 
- 单击 debug.bat,并在 Visual Studio 中按 F11(逐语句)调试脚本。 
- 在脚本中查找错误并修复它。 

如果成功,脚本将调用 Google 翻译服务,发送消息,下载生成的 voice mp3 文件,并播放它。 

(请注意,Google 可能会更改 URL。实际 URL 可以在其页面 https://translate.google.com/ 上使用类似 firebug 的工具找到) 

 

第二部分:Windows Web 服务器 (IIS) 中的 JavaScript

现在我们已经可以在服务器端为 Windows 创建 JavaScript 程序了, 
让我们为 IIS(IIS 是所有 Windows 操作系统中内置的 Web 服务器)创建一个 JavaScript 程序。 
(请注意 - 以下步骤不适用于托管或生产环境,仅适用于本地开发环境。任何版本的 Windows 都可以,甚至 XP SP2) 

步骤: 
 - 确保 IIS 已启动并运行。 
 - 在 IIS 中启用脚本调试。 
 - 在 IIS 中启用 ASP 脚本(又名 Classic ASP)。 
 - 在 Web 服务器的根文件夹(通常是 c:\inetpub\wwwroot\)中创建一个新文件 test.asp。 

为什么是“.asp”?原因是我们将使用一个内置的 IIS 脚本引擎,该引擎支持 Web 页面的 JavaScript 场景。 

 - 在记事本中打开 test.asp 文件,并插入以下代码。 

 

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

 - 保存文件。 
 - 打开浏览器并导航到页面 https:///test.asp。 

 

系统应显示消息“Hello world!”。 

这里发生了什么: 
当您打开 URL 时,您的浏览器会将 GET 请求发送到具有该 URL 的服务器。 
IIS 服务器会在文件夹中找到文件夹和文件(在本例中,文件夹位于根文件夹中),并将文件加载到脚本引擎中(请注意,如果 IIS 找不到文件夹或文件,将为 404 错误调用错误处理程序。我们将在稍后使用此功能来实现格式美观的 URL)。脚本引擎读取伪标签 <% 和 %> 之间的代码并执行找到的代码。默认情况下,VBScript 用作脚本语言。您可以使用 IIS 设置或指令重新定义默认脚本语言 
<%@  language="javascript" %>,这应该是文件中的第一条指令。 

因此,在脚本引擎加载文件后,JavaScript 代码将被执行。变量msg获取字符串值。然后,该变量的值与脚本文件中的 HTML 内容通过Response.Write()调用合并。 由于脚本文件中没有 HTML 内容,因此唯一的输出是“Hello world!”消息。 

在此处阅读有关内置 Response 对象的更多信息: 
https://w3schools.org.cn/asp/asp_ref_response.asp 

我们将使用的其他内置对象在此处: 
https://w3schools.org.cn/asp/ 

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

 

调试: 

将 debugger 指令放在代码行之前,如下所示: 

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

如果正确设置了 IIS 脚本调试,您的代码将在 Visual Studio 中以调试模式执行。 

 

接收 GET 值: 

步骤

- 将 test.asp 中的代码替换为以下代码: 

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

  
%> 

- 打开浏览器并导航到页面 https:///test.asp?c=home&a=index。 
- IIS 将显示带有以下内容的页面: 

  {controller:home,action:index} 


在此处阅读有关从 Classic ASP 中的 Request 获取值的更多信息: 
https://w3schools.org.cn/asp/coll_querystring.asp 

 

结构化代码

让我们修改上面的代码如下: 

<%@  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(); 
%> 

步骤

 - 保存代码。 

 - 打开浏览器并导航到 URL。 

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

您应该看到消息“Hello world!”。 

这里重要的是: 

1. 我们创建了应用程序的单一入口点 - 一个路由()函数。 
当调用此函数时,它会将请求路由(传递执行) 到相应的 Controller 和 Action。在本示例中,只有一个 Controller - “homeController”,它只有一个 Action - “hello” Action;但是,您可以扩展应用程序的逻辑。 
实际上,MVC 模式在这里应用于代码。 

如果由于代码分离而带来的逻辑纯粹性没有让您相信使用这种“不必要的复杂性”的代码,请在网上搜索更多关于 mvc 架构模式的信息。 

2. “Controllers”数组允许限制代码执行。如果我们不限制它,那么某些恶意的有效 JavaScript 可能会被执行。 

3. 模块的局部变量在请求之间不会保留值。如果您想在两次请求之间保存某些内容,请使用数据库或会话变量。 

 

扩展模块逻辑

让我们像下面这样扩展 homeControler,添加一些新的 Action: 

<%@  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(); 
%> 

 尝试导航以下链接: 

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

 

 

添加另一个 Controller

<%@  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(); 
%> 

 

- 尝试使用以下 URL: 

1 个测试用例

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

 

2 个测试用例

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

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

 

3 个测试用例

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

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

 

历史

所有示例均在 Windows 2003、IIS 6 上测试过。 

本文旨在回答用户 jaked6803 和 kangchoi 的疑问。我很抱歉,无法回答所有问题,因为需要解释的事情太多了。 关于如何在 Windows 中使用 JavaScript 的简单教程很少。我希望这项努力能帮助您开始在 Windows 中使用 JavaScript,并使其痛苦程度降低。 

© . All rights reserved.