[转帖]学习如何使用客户端和服务器端上的 HTML/DOM/JavaScript 支持构建 Jaxer 应用程序_MySQL, Oracle及数据库讨论区_Weblogic技术|Tuxedo技术|中间件技术|Oracle论坛|JAVA论坛|Linux/Unix技术|hadoop论坛_联动北方技术论坛  
网站首页 | 关于我们 | 服务中心 | 经验交流 | 公司荣誉 | 成功案例 | 合作伙伴 | 联系我们 |
联动北方-国内领先的云技术服务提供商
»  游客             当前位置:  论坛首页 »  自由讨论区 »  MySQL, Oracle及数据库讨论区 »
总帖数
1
每页帖数
101/1页1
返回列表
0
发起投票  发起投票 发新帖子
查看: 2618 | 回复: 0   主题: [转帖]学习如何使用客户端和服务器端上的 HTML/DOM/JavaScript 支持构建 Jaxer 应用程序        下一篇 
Xuziwen
注册用户
等级:上尉
经验:721
发帖:66
精华:0
注册:2012-7-4
状态:离线
发送短消息息给Xuziwen 加好友    发送短消息息给Xuziwen 发消息
发表于: IP:您无权察看 2014-11-5 14:26:38 | [全部帖] [楼主帖] 楼主

传统上,要为基于 Web 的客户机提供比较丰富的客户机功能,必须创建基于 Web 的应用程序,它由来自各种不同技术的同质系统组成,其中可能包括:

服务器端 Web 或应用服务器,比如 Apache HTTP Server、 Microsoft® Internet Information Services (IIS)、Sun Java™ Web Server、IBM® WebSphere® 或 BEA WebLogic
服务器端脚本或处理语言,比如 Java、PHP、JavaServer Pages™ (JSP) 或 Active Server Pages (ASP)
客户端脚本和格式化,比如 HTML、Cascading Style Sheets (CSS)、JavaScript 或 DOM
HTTP 通信协议或应用程序编程接口 (API),比如 XMLHttpRequests 或 JavaScript Serialized Object Notation (JSON)
Ajax 资源中心
请访问 Ajax 资源中心,这是有关 Ajax 编程模型信息的一站式中心,包括很多文档、教程、论坛、blog、wiki 和新闻。任何 Ajax 的新信息都能在这里找到。

但是现在,您可以使用 Jaxer,一种新的 Ajax 服务器,不仅将所有这些技术集成到一个可部署服务器中,还使用一些相同的基于客户端技术(比如 JavaScript 代码、DOM 等)提供了服务器端脚本和处理。Jaxer 是免费的开源代码,您可以原样使用,或者使用其 JavaScript 框架进一步扩展。

想象一下,能够直接在 HTML 页面中使用 JavaScript 代码,并简单指明代码应在客户端返回 HTML 之前在服务器端执行。这将允许客户端直接与服务器端进一步通信,而无需刷新页面。此外,得到的 HTML 可以基于在服务器端执行的 JavaScript 代码。这将减少需要使用的技术种类和您必须编写的代码量,从而为开发人员和用户提供更好的整体体验。

对于用户,您现在可以提供与富原生应用程序更接近的基于 Ajax 的功能。Jaxer 使其成为可能,因为它实际上是第一个真正的 Ajax 服务器。您不需要确定您的 Ajax 代码运行在哪个浏览器中。您也不必编写协议代码来执行服务器通信。通过调用简单的 Jaxer API,您提供了具有最少缺陷的健壮的 Web 应用程序。甚至更重要的是,您再也不必使用内嵌的 JavaScrip 公开所有代码。您实际上可以使用 Jaxer 统一客户机代码与服务器代码,将策略代码安全地隐藏在防火墙后面,并允许它仍可从客户机访问。

在使用 Jaxer 开发任何基于 Web 的应用程序之前,您首先必须将其安装在您的机器或开发环境中。有三个选择。Jaxer 可用于 Microsoft Windows®、Mac OS X 或 Linux®。Jaxer 安装是自包含、独立的 Apache/Jaxer 服务器。但是,您还可以在现有的 Apache 或 Jetty 环境中将其作为模块安装。Aptana 报告计划在不久的将来支持 IIS。

出于本文目的,因为大多数开发人员在 Windows 上编码,然后部署到 Windows 或 *NIX 环境(比如 UNIX® 或 Linux)中,所以我选择安装独立的 Windows 版本。在 Windows 上安装十分简单。您只需转至 Aptana Jaxer 下载页面(请参见 参考资料 中此页面的链接),并下载 Windows 独立版本的压缩文件(.zip)。在撰写本文时,最新的版本是 0.9.7.2472。

下载并打开压缩文件之后,将 Aptana Jaxer 文件夹复制到硬盘驱动器上。我直接复制到我的 C: 驱动器上。因此,我可以通过转至 C:\Aptana Jaxer 访问我的根文件夹来访问 Jaxer。

Aptana Jaxer 文件夹中有许多文件和文件夹。根文件夹包含下列文件:

ConfigureFirewall.exe
LICENSE.TXT
README.TXT
StartServers.bat


它还包含下列文件夹:

Apache22
data
jaxer
local_jaxer
logs
public


启动并测试 Jaxer 服务器
启动服务器甚至比前面的安装更简单。只需运行 StartServers.bat 文件,然后就显示启动窗口,如图 1 所示。

图 1. Jaxer 启动窗口
只要您打算在 Jaxer 环境中使用和测试应用程序,就必须一直打开此窗口。通过打开浏览器窗口并导航至 http://localhost:8081/aptana,可以测试 Jaxer 服务器是否正在正常运行。About Jaxer 页面显示在浏览器中,如图 2 所示。

图 2. About Jaxer 页面
Samples 文件夹中还有其他基于 Jaxer 的 Web 应用程序,位于 <jaxer_install_dir>\jaxer\aptana\samples 中。您将找到几个应用程序,其中包括表 1 中描述的那些。

表 1. Jaxer Samples 文件夹中包括的应用程序

 csajax


使用 Ajax 为那些尝试使用 JavaScript 代码与客户机浏览器某些域通信的 Web 应用程序通常面临的问题提供解决方案。相反,基于浏览器的客户机使用 Jaxer 与服务器通信,然后允许服务器与其他域通信,实际上为跨站点问题提供了解决方案。有关此问题的更多信息,请参见 “参考资料”。

 logging


展示如何包装服务器端日志并使用客户端 JavaScript 进行访问。

 rss-sample


演示可以如何划分页面以在页面的一部分中显示新故事列表,并在页面的另一部分中显示选定的故事。故事显示在自己的区段中,而不会刷新整个页面;一切工作使用 Ajax 和 Jaxer 完成。

 smtp-email


允许使用 Jaxer Simple Mail Transfer Protocol (SMTP) 对象异步发送电子邮件。

 tasks


允许使用异步通信在单个 to-do 或任务列表中添加、修改或删除项目。

 wikilite


允许用户以编辑模式为简单的 wiki 提供文本,保存文本,然后在将来查看文本。
可以通过单击图 2 所示的 Samples and Tools 链接,访问这些示例。得到的 Samples and Tools 页面如图 3 所示。

图 3. Samples and Tools 页面
在本文后面,您将使用任务示例应用程序进一步了解 Aptana Jaxer。

您可能已经注意到,还有几个 Web 工具和诊断工具可用于与 Jaxer 交互,并在出现问题时诊断问题。例如,单击 Server Diagnostics 链接返回 Jaxer Diagnostics 页面,如图 4 所示。

图 4. Jaxer Diagnostics 页面
添加内容
介绍 Jaxer 根文件夹时,我提到了它里面有几个子文件夹。其中一个文件夹名为 public。您可以使用此文件夹提供自己的内容。如果这样做,而且您仅在浏览器地址行中指定 host:port 地址,则它将从浏览器中调用。例如,http://localhost:8081/ 返回您提供的任何索引文件。

甚至更好的是,您可以在 public 文件夹中创建多个项目,并通过名称加载项目。例如,创建名为 my_project 的项目。此文件夹的完整路径应为 C:\<jaxer_root>\public\my_project。

现在,创建名为 index.html 的索引文件,并将其放入 my_project 文件夹中。通过在浏览器中输入其路径,可以使用 Jaxer 服务器加载此文件。在这种情况下,输入 http://localhost:8081/my_project。可以在此文件夹或其任何子文件夹中放置任何 HTML、图片、JavaScript 文件或 CSS 文件。

在我的 my_project 中,我选择创建一个 index.html 文件,它是从 Aptana 网站上获得的快速启动代码中借来的。此代码演示了服务器端 DOM、JavaScript 代码和回调,如清单 1 所示。

清单 1. 测试 Jaxer 的示例代码

 <html>
<head>
<title>Quick Jaxer Sample</title>
</head>
<body>
<h3>Quick Jaxer Sample</h3>
<p>This demonstrates server-side DOM, JavaScript and callbacks.</p>
<script runat="server-proxy">
document.write("This is Jaxer version " + Jaxer.buildNumber);
function getLatestVersion() {
var url = "http://update.aptana.com/update/jaxer/win32/version.txt";
try {
var versionString = Jaxer.Web.get(url);
catch (e) {
throw "Could not retrieve version number from " + url;
var matches = versionString.match(/\"([\.\d]+)\"/);
return (matches && matches.length > 1) ? matches[1] : "(unknown)";
</script>
<input type="button" value="Check Latest" onclick="alert('Latest version: '
+ getLatestVersion())">
</body>
</html>


执行时,此代码生成如图 5 所示的页面。

图 5. my_project 中使用的快速启动代码
如果查看发送到浏览器中的实际 HTML 源码,您将发现它与原始代码非常不同。请看清单 2。

清单 2. 返回给浏览器的 Jaxer 生成的 HTML 代码

 <html><head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
<script src="\jaxer\framework\clientFramework_compressed.js?
version=0.9.7.2472"></script>
<script>Jaxer.Callback.pageSignature = -1837648436;
Jaxer.Callback.pageName = 'localhost:8081/my_project';
Jaxer.CALLBACK_URI = '/jaxer-server/callback';
Jaxer.ALERT_CALLBACK_ERRORS = true;</script>
<title>Quick Jaxer Sample</title>
</head><body>
<h3>Quick Jaxer Sample</h3>
<p>This demonstrates server-side DOM, JavaScript and callbacks.</p>
<script>
function getLatestVersion() {return Jaxer.remote("getLatestVersion", arguments);}
function getLatestVersionAsync(callback) {return Jaxer.remote(
"getLatestVersion", arguments, callback);}
</script>This is Jaxer version 0.9.7.2472
<input value="Check Latest" onclick=
"alert('Latest version: ' + getLatestVersion())" type="button">
</body></html>


注意,原始代码不需要包括任何外部 JavaScript 文件。接下来,查看一下 <script> 块封装的 JavaScript 部分。此代码与通常为浏览器编写的 JavaScript 代码之间的惟一差别是,此代码使用 runat 属性指定此代码应使用 server-proxy 执行。

Jaxer 高级视图
在查看 Jaxer 架构之前,首先看一下传统应用程序的架构,如图 6 所示。

图 6. 传统应用程序堆栈
所有堆栈从客户机到服务器的请求开始。在传统情况下,服务器端使用一种或多种技术处理请求来进行响应,这些技术可能包括 PHP、Java 代码、C#、Ruby On Rails 或任何数量的其他脚本/对象技术。服务器端可以执行数据库或文件访问,处理数据,然后格式化数据,并将其返回给浏览器。这些技术是单独的组件,必须通过连接代码连接在一起。

如果基于 Web 的应用程序使用 Ajax,它必须采取步骤来处理客户端请求,封装调用/参数,并发送请求。在服务器端,代码必须打开请求以确定调用/参数,然后执行调用,接收响应,重新封装响应,并将其返回给客户机。然后,客户机必须展开响应,最后进行处理。封装/打开可以使用 JSON 完成,实际的请求/响应/回调可以使用 XMLHttpRequest 完成。相比之下,请查看一下 Jaxer 堆栈,如图 7 所示。

图 7. Jaxer 应用程序堆栈
注意,堆栈要简单得多。还要注意,无需外部脚本;全部操作在实际的 HTML 中处理。通过使用 runat 属性指定位置,JavaScript 代码只瞄准它运行的位置。

当客户机代码需要调用服务器端时,Jaxer 无缝地将 JavaScript 包装器代码封装到返回给浏览器的 HTML 中。这就是清单 2 为什么与清单 1 中的原始代码有所不同的原因。

如果您觉得奇怪的话,Jaxer 的核心实际是用 C++ 编写的。它还集成了 Mozilla 引擎,为 HTML、CSS 和 JavaScript 代码提供解析和 API。从程序员观点来看,您看到的是作为框架提供的纯 JavaScript 代码,可用于实现服务器端 JavaScript 代码和客户端 Ajax。

Jaxer 提供服务来支持应用程序的开发,其中需要下列技术:

Ajax


来自客户机或服务器的数据库通信
客户端或服务器端日志
会话操作
客户端或服务器端网络 API 连接
文件对象
等等……
此外,可以将 Jaxer 与传统技术(比如 Java 代码)集成以帮助解决跨平台问题。

为了更好地理解如何构建 Jaxer 应用程序,我想为您演示 Jaxer 附带的示例站点。您将查看任务应用程序,您可以通过转至 http://localhost:8081/aptana/samples/tasks 来访问它。将显示图 8 所示的页面。我已经添加了一些任务。

图 8. 任务示例主页面
从用户观点来看,任务应用程序非常简单。您只需在 New 框中键入新任务并单击 add。要删除项目,只需单击您要删除的项目旁边的复选框。

请查看清单 3,其中显示了任务 HTML 页面中嵌入的一些 JavaScript 代码。

清单 3. 客户机和服务器上运行的任务 JavaScript 代码

 <script type="text/javascript" runat="both">
* Easy access to a named element in the DOM
function $(id)
return document.getElementById(id);
function addTaskToUI(description, id)
var newId = id || Math.ceil(1000000000 * Math.random());
var divnbsp&= document.createElement("div");
div.id = "task_" + newId;
div.className = "task";
var checkbox = document.createElement("input");
checkbox.setAttribute("type", "checkbox");
checkbox.setAttribute("title", "done");
checkbox.setAttribute("id", "checkbox_" + newId);
Jaxer.setEvent(checkbox, "onclick", "completeTask(" + newId + ")");
div.appendChild(checkbox);
var input = document.createElement("input");
input.setAttribute("type", "text");
input.setAttribute("size", "60");
input.setAttribute("title", "description");
input.setAttribute("id", "input_" + newId);
input.value = description;
Jaxer.setEvent(input, "onchange",
"saveTaskInDB(" + newId + ", this.value)");
div.appendChild(input);
$("tasks").insertBefore(div, $("tasks").firstChild);
if (!Jaxer.isOnServer)
saveTaskInDB(newId, description);
</script>


首先,注意有多个 JavaScript 块。第一个块具有自己的 runat 属性集,这意味着其中的代码将可用于客户机和服务器端。清单 3 中的函数提供了可由在客户机和服务器端上执行的其他函数访问的一般函数。$ 函数只基于提供的 ID 返回一个元素。addTaskToUI 使用 createElement 和 insertBefore 方法创建用户接口,在客户端提供任务。

此处对任何特定于 Jaxer 的 API 没有太多调用,只有附加到输入和复选框的事件定义,以及与 Jaxer.isOnServer 属性的逻辑比较,如果 JavaScript 代码当前在服务器端执行,Jaxer.isOnServer 则设置为真。

Jaxer.setEvent 用于建立通信代理,此代理用于从客户机对服务器进行调用。在下文中,我将详细介绍。

基于传递给 runat 属性的值,下一段 JavaScript 代码固定在服务器上运行,如清单 4 所示。

清单 4. 任务服务器端 JavaScript 代码

 <script type="text/javascript" runat="server">
* The SQL to create the database table we'll use to store the tasks
var sql = "CREATE TABLE IF NOT EXISTS tasks " +
"( id INTEGER NOT NULL" +
", description VARCHAR(255)" +
", created DATETIME NOT NULL" +
")";
// Execute the sql statement against the default Jaxer database
Jaxer.DB.execute(sql);
* Set the 'onserverload' property to call our function
* once the page has been fully
* loaded server-side. We could have also set this attribute
* on the <body> tag of our
* page and had it call a function by name.
window.onserverload = function()
var resultSet = Jaxer.DB.execute("SELECT * FROM tasks ORDER BY created");
for (var i=0; i<resultSet.rows.length; i++)
var task = resultSet.rows[i];
addTaskToUI(task.description, task.id);
* Save a task directly into the database
function saveTaskInDB(id, description)
var resultSet = Jaxer.DB.execute(
"SELECT * FROM tasks WHERE id = ?", [id]);
if (resultSet.rows.length > 0) // task already exists
Jaxer.DB.execute("UPDATE tasks SET description = ? WHERE id = ?",
[description, id]);
else // insert new task
Jaxer.DB.execute("INSERT INTO tasks (id, description, created) " +
"VALUES (?, ?, ?)",
[id, description, new Date()]);
// Because we want this function callable from the client, we set its proxy
// value to true
saveTaskInDB.proxy = true;
* Delete a task from the database
function deleteSavedTask(id)
Jaxer.DB.execute("DELETE FROM tasks WHERE id = ?", [id]);
// Because we want this function callable from the client, we set its proxy
// value to true
deleteSavedTask.proxy = true;</script>


运行此示例时,请在浏览器中查看由 Jaxer 生成的源代码。注意,清单 4 中的代码消失了。非常方便的是,定义的函数已经转换为真实函数的简单 shell。取而代之的是,创建了简单的 Jaxer 远程。

清单 4 提供了一些有趣的 JavaScript 代码。虽然全部是 JavaScript 代码,但要现在可以在服务器端定义和运行 JavaScript 代码。在此代码段的第一部分中,注意创建了 Structured Query Language (SQL) 表(如果不存在的话)。接下来,建立了类似浏览器端的 onload 的事件,只不过这个位于服务器端。在 Jaxer 加载整个文件,并记录所有的全局服务器函数和变量之后,调用定义并分配给 onserverload 的函数。

在本例中,定义的方法包括 saveTaskInDB 和 deleteSavedTask。要让函数可从客户端调用,必须定义代理。通过将函数的 proxy 属性设置为真,可完成此操作。

Jaxer 加载文件之后,分配给 onserverload 的功能将执行。在本例中,函数执行 SQL 调用从数据库中检索现有任务。接下来,它继续遍历所有任务并调用 addTaskToUI 方法。如果您没记错的话,此方法将复选框和输入框插入到 HTML 文档中。但等一等!在本例中,这将意味着,服务器实际正在将这些复选框和输入框推入文档中。在服务器端执行此代码时,惟一在 addTaskToUI 中不执行的代码是逻辑检查中封装的代码,用于查看 isOnServer 是真还是假。只有客户端需要这段代码,用于对服务器执行远程调用,以将任务添加到数据库中。

清单 4 的函数中散布着各种 Jaxer 调用,大多数用于处理数据库交互。而且,您可以看到,不需要任何外部组件、facade 或 Data Access Objects (DAO)。它使用对 Jaxer API 的简单调用来执行 SQL 函数。切记,没有什么可以阻止您使用更特定的 JavaScript 组件封装这些简单的调用,这些组件似乎更熟悉数据库的实际详细信息,实际上通过 SQL 数据库提供了一个 facade。

任务示例中其余的 JavaScript 代码只处理您与表单控件交互时发生的事件,如清单 5 所示。

清单 5. 任务中其余的 JavaScript 代码,仅在客户端执行。

 <script type="text/javascript">
* This client function sets a task as completed and
* calls the server-side function
* 'deleteSavedTask' to remove it from the database
function completeTask(taskId)
var divnbsp&= $("task_" + taskId);
div.parentNode.removeChild(div);
deleteSavedTask(taskId);
* Create a new task and add it to the user interface
function newTask()
var description = $('txt_new').value;
if (description != '')
addTaskToUI(description);
$('txt_new').value = '';
* Create a new task if the enter key was hit
function newKeyDown(evt)
if (evt.keyCode == 13)
newTask();
return false;
</script>


此代码是普通的旧 JavaScript 客户机代码,仅在客户端执行。但是要注意,这些函数调用了服务器端 JavaScript 代码中封装的函数。HTML 生成的代码为这些函数提供代理方法,这些方法调用服务器端的远程方法。服务器端方法的实际函数或代码绝不公开给客户端。

我希望您能够看到 Jaxer 必须提供的巨大潜能,甚至是在早期阶段。是的,它正出于萌芽阶段,可能还有待成熟。但是,它展示了许多承诺。毕竟,它可以在服务器端运行 JavaScript 代码,在客户端运行 Ajax,而且构建于许多现有的成熟技术之上,仅仅这些事实就足够有说服力。它很容易设置,而且可以运行在现有 Web 服务器环境中,而不出现任何问题,或很少出现问题。我在我的 Windows 机器上进行了尝试,该机器当前运行 Apache 以及 PHP、MySQL 等,没有出现任何问题。它从来没有停止我的其他 Apache 实例,而且能够在端口 8081 上与 Jaxer 实例通信,也没有出现问题。我看到的惟一可能出现问题的情况是,您当前正将端口 8081 用于其他地方(比如 Tomcat)。

--转自 北京联动北方科技有限公司




赞(0)    操作        顶端 
总帖数
1
每页帖数
101/1页1
返回列表
发新帖子
请输入验证码: 点击刷新验证码
您需要登录后才可以回帖 登录 | 注册
技术讨论