适用于 Windows 服务器端的 JavaScript。
在 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,并使其痛苦程度降低。