ajax脚本下载
ECMAScript for XML
您可能以前没有碰过术语ECMAScript 。 它实际上是JavaScript的正式名称。 欧洲计算机制造商协会(ECMA)是JavaScript标准化的标准机构(也是C#和CLR标准化的地方)。 可从ECMA网站免费获得ECMAScript标准。
E4X是JavaScript的扩展,它为语言增加了对XML的直接支持。 这也是一个ECMA标准(参见相关主题 - ECMA-357)。 那么什么是直接支持,为什么有价值? 如果您是JavaScript程序员,则可能已经使用Netscape LiveConnect或Rhino(在Java™下运行的免费可用JavaScript库)之类的技术来将Java库与JavaScript一起使用。 这意味着您已经可以借助XML库来创建,操作和使用XML。 同样,如果使用Microsoft®Internet Explorer,则可以通过Microsoft MSXML2库获得XML支持。 好吧,如果您使用过这些库,请为进行重大更改做准备-E4X变得更加简单易用。
在查看示例之前,请先尝试一下:E4X目前在两种实现中可用。 两者都可以从Mozilla获得。 一个是浏览器使用的C JavaScript引擎(代号SpiderMonkey),它可以在最新的Mozilla构建中使用-我们使用的是Mozilla 1.8a6。 Rhino也提供E4X。 Rhino是用Java内置JavaScript解释器和编译器,我们将演示它们是独立的并在Axis中运行。 两者都可以从Mozilla获得 。
在这些示例中,我们首先在Rhino的命令行上使用E4X,然后再在Mozilla的浏览器中使用E4X,以演示AJAX模型。 在第二篇文章中,我们将向您展示如何通过将Rhino嵌入Apache Axis Web服务引擎中来在服务器中使用E4X。 但是,在继续进行Web服务之前,我们将向您展示E4X中XML编程的基础。
一个简单的例子
让我们从一个简单的例子开始。 我们解析并处理一个XML,该XML表示有关作者的一些信息。 我们想要的XML如下所示:
清单1.作者
<people>
<person gender="male">
<name>Ant</name>
<hair>Shaggy</hair>
<eyes>Blue</eyes>
<height measure="metric">176</height>
</person>
<person gender="male">
<name>Paul</name>
<hair>Spiky</hair>
<eyes>Grey</eyes>
<height measure="metric">178</height>
</person>
</people>
如果我们将其包含在字符串中,则只需执行以下操作即可“解析”该字符串:
var x = new XML(peopleXMLString);
另外,我们可以简单地在代码中“内联” XML:
var x =
<people>
<person gender="male">
<name>Ant</name>
<hair>Shaggy</hair>
<eyes>Blue</eyes>
<height measure="metric">176</height>
</person>
<person gender="male">
<name>Paul</name>
<hair>Spiky</hair>
<eyes>Grey</eyes>
<height measure="metric">178</height>
</person>
</people>;
是的-是的-XML成为语言的直接组成部分。
在Rhino上使用E4X
如果您和我们一样,现在就想尝试一下。 最新版本的Rhino 1.6R1与Apache的XMLBeans库一起支持E4X。 只需抓取这些软件包,解压缩它们,然后将js.jar和xbean.jar添加到您的类路径中,然后启动JavaScript shell。
java -cp js.jar;xbean.jar org.mozilla.javascript.tools.shell.Main
现在,您可以尝试以下示例。 您可以从此处剪切并粘贴它们,也可以将它们包含在文件examples1.js中,该文件位于zip文件(ws-ajax1code.zip)中,您可以通过单击顶部的代码图标进行下载。或本文的底部。
您可以仅使用JavaScript属性来引用XML的任何部分。 例如:
print(x.person[0].name);
Ant
print(x.person[1].hair);
Spiky
您是否注意到我们没有使用DOM或SAX等XML API? XML已经简单地成为JavaScript可以理解的本机类型之一。
使用以下命令打印出两个人的身高:
for each (var h in x..height) { print(h) };
176
178
..
语法非常有用。 它返回与以下标记名匹配的所有深度的所有子元素。 因此x..height
返回height
标签的值。
另一个有用的语法如下:
print(x.person.(name=="Ant").hair);
Shaggy
这使得在树内进行查找非常简单。
一个更复杂的例子
假设您要将高度从公制更改为英制(这就是我们英国人所说的英尺和英寸)。
首先是从厘米到英寸的换算...
function metricToImperial(cms) {
var totalinches = Math.round(cms/2.54);
var inch = totalinches%12;
var ft = (totalinches-inch)/12;
var response = <height/>;
response.feet = ft;
response.inches = inch + 2; // we sounded a bit short
response.@measure = "imperial";
return response;
}
第一个有趣的行是这样的:
var response = <height/>;
该行允许您在JavaScript中“内联” XML。 此语法有两个好处。 首先,它使使用XML变得非常容易。 其次,代码的含义很明确。
现在,您可以向该元素添加更多子元素:
response.feet = ft;
这将创建<height>
的子元素,其标签名称设置为“ feet”,其值设置为变量ft
的值。
您还可以通过以下方式操作属性:
response.@measure = "imperial";
现在,让我们使用此函数来更新XML:
for each (var p in x.person) {
if (p.height.@measure=="metric")
p.height=metricToImperial(p.height);
}
print (x);
这是输出:
<people>
<person gender="male">
<name>Ant</name>
<hair>Shaggy</hair>
<eyes>Blue</eyes>
<height measure="imperial">
<feet>5</feet>
<inches>11</inches>
</height>
</person>
<person gender="male">
<name>Paul</name>
<hair>Spiky</hair>
<eyes>Grey</eyes>
<height measure="imperial">
<feet>5</feet>
<inches>12</inches>
</height>
</person>
</people>
E4X中的XML命名空间
如果您是XML专家,那么此时,您可能想知道如何使用此语法管理XML命名空间。 有三种方法可以做到这一点:
首先,您可以使用嵌入式XML语法:
var soapMsg = <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope"/>;
print(soapMsg.namespace());
http://www.w3.org/2003/05/soap-envelope
下一种方法是在创建元素之前设置默认的XML命名空间:
default xml namespace = new Namespace("http://www.w3.org/2003/05/soap-envelope");
您可以通过将默认名称空间设置为空字符串来重置默认名称空间:
default xml namespace = ""
最后一种方法是使用::
运算符
var f = new Namespace("http://fremantle.org");
soapMsg.Body.f::GetStockQuote="IBM";
print(soapMsg);
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope">
<s:Body>
<frem:GetStockQuote xmlns:frem="http://fremantle.org">
IBM
</frem:GetStockQuote>
</s:Body>
</s:Envelope>
XML元素排序
E4X的一大优点是它完全支持XML,包括订购。 从XML直接映射到语言对象的许多映射最终仅支持与常规对象语义相匹配的XML语义子集-因此缺少表示对象和文档的能力。 尽管不适合本文,但快速浏览该规范将发现E4X XML对象具有的内置函数允许精心设计XML的顺序。
在XML中使用Javascript表达式
在继续使用Web服务之前,我们还有最后一件事要告诉您-大括号。 上面我们介绍了“内联” XML。 E4X还使您可以重新进入JavaScript的世界,并包含评估表达式。 因此,例如:
var num = 36;
var p = <paul><age>{num}</age></paul>
print(p);
<paul>
<age>36</age>
</paul>
现在,我们已经介绍了E4X的基础知识,因此让我们对其进行一些工作。
使用E4X调用Web服务
在本节中,我们描述如何在以下两种环境中使用E4X:
- 带有XMLHttpRequest的Mozilla 1.8
- Java /犀牛
您可以非常轻松地使用E4X在浏览器中调用Web服务。 不过有一个问题! 到目前为止,唯一支持E4X的浏览器是Mozilla 1.8的开发人员版本。
虽然我们不建议您将此作为可移植的跨浏览器解决方案,但以下示例演示了如何使用E4X以简单的方式调用Web服务。 在下一节中,我们将介绍在Rhino Javascript引擎中有效的另一种方法。
AJAX
这个简单的示例显示了浏览器向SOAP服务器发送和接收SOAP消息的过程。 为此,我们将E4X与XMLHttpRequest对象一起使用。 这个有用的对象(Mozilla和Internet Explorer支持)允许浏览器中运行的脚本在后台发出HTTP请求。 实际上,这就是Google的GMail几乎执行所有操作的方式。 该体系结构最近被命名为异步JavaScript + XML(AJAX)。 您可以在文章“ Ajax:Web应用程序的新方法”中阅读有关AJAX的更多信息(请参阅参考资料 )。
从根本上讲,AJAX的想法是通过以比标准HTML和HTTP的“页面”模型更灵活的方式与服务器交互来提高网页的响应能力和可用性。 一个很好的例子是Google Maps beta,它比以前的地图网站更具交互性。
好消息是,结合了E4X的AJAX甚至更好! 我们将显示两个版本的浏览器应用程序。 第一个演示了交互的工作原理,而第二个版本则隐藏了网页的按钮和内部工作原理,以显示交互性和异步性。
浏览器安全
为了证明这一点,我们使用了xmethods.net上通过Web提供的标准服务。 但是,有一个陷阱! 浏览器安全规则通常不允许脚本或Java小程序创建网络连接,但不能连接到页面所在的服务器。 否则,您可能会有一个间谍软件页面,将您的击键复制到另一台服务器。
但是,您可以解决此问题。 为此,您需要执行两个步骤。 首先,您必须在Mozilla的配置中为脚本启用增强的特权。 (假设您已经下载并安装了Mozilla 1.8 beta)。
在浏览器地址栏中键入about:config
,然后将signed.applets.codebase_principal_support
的值从false
更新为true
。 (出于安全原因,请记住在完成操作后再设置一次。)
然后,在脚本中,您可以要求增强的特权。 脚本运行时,将提示用户允许使用这些脚本。 代码行是:
netscape.security.PrivilegeManager.enablePrivilege( "UniversalXPConnect UniversalBrowserAccess");
另一种选择是将服务和网页部署到Web应用程序服务器中,例如IBM®WebSphere®Application Server或Tomcat。 例如,这适用于Apache Axis和Axis随附的默认股票报价器示例(请参阅参考资料 )。
股票报价客户样本
该脚本是stockclient.html的一部分。 如果从本文下载了ws-ajax1code.zip文件,解压缩了zip内容,然后使用Mozilla打开stockclient.html ,则应该看到以下内容:
图1. Mozilla中的stockclient.html
要尝试,请首先点击更新URL 。 这使用XMLHttpRequest从http://services.xmethods.net/soap/urn:xmethods-delayed-quotes.wsdl(或在WSDL框中键入的任何URL)中获取WSDL文件,然后使用E4X捕获端口从那里的地址URL。 现在单击Send ,您应该会看到SOAP请求已填写。再过一两秒钟,SOAP响应以及结果字段都将更新。 让我们看一下代码。
股票报价客户端脚本
该脚本调用该URL并请求提供IBM股票价格。 如果您使用的是Axis服务器,我们建议使用股票代号XXX,这是一个特殊符号-部署的服务将始终为此股票代号返回固定的响应,而不是通过Web请求查找实际价格-因此,这样做更好用于测试。
您需要做的第一件事就是定义您希望使用E4X:
<script type="text/javascript;e4x=1">
当您按下发送按钮时,脚本将执行以下操作:
var s = new Namespace(
"s",
"http://schemas.xmlsoap.org/soap/envelope/");
var envelope = <s:Envelope xmlns:s={s}/>;
envelope.s::Body="";
var body = envelope.s::Body;
这对任何SOAP请求都是通用的。 它只是创建一个带有空主体的SOAP信封。
执行此操作的等效方法如下:
var envelope =
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body/>
</s:Envelope>
但是,前面的代码更简单,并且还为您提供了一个指向body元素的指针。
下一步是创建消息的正文:
var x = new Namespace("x","urn:xmltoday-delayed-quotes");
body.x::getQuote = <x:getQuote xmlns:x={x}/>;
最后,您需要添加正确的符号:
var symbol = document.getElementById("symbol").value;
var getQuote = body.x::getQuote;
getQuote.symbol=symbol;
现在,您有了一个格式完整的SOAP请求。 如果您要评估信封,您将获得以下信息:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<x:getQuote xmlns:x="urn:xmethods-delayed-quotes">
<symbol>XXX</symbol>
</x:getQuote>
</s:Body>
</s:Envelope>
要发送此消息,您需要使用XMLHTTPRequest对象。 我们创建了一个简单的辅助函数,以支持使用XMLHttpRequest对象来调用使用E4X的服务。 函数execService
支持异步和同步使用。
function execService(url, xml, callback) {
var xmlhttp = new XMLHttpRequest();
var async=false;
if (arguments.length==3) async=true;
xmlhttp.open("POST", url, async);
xmlhttp.setRequestHeader("SOAPAction", "\"\"")
xmlhttp.setRequestHeader("Content-Type", "text/xml")
if (async) {
var f = function() {
if (xmlhttp.readyState==4) {
callback(new XML(xmlhttp.responseText));
}
}
xmlhttp.onreadystatechange = f;
}
xmlhttp.send(xml.toString());
if (!async) return new XML(xmlhttp.responseText);
}
让我们更详细地看一下代码。 首先,代码支持两种调用方式。 您可以致电:
XML execService(String url, XML envelope);
要么
void execService(String url, XML envelope, function callback);
在这种情况下,回调函数应为void callback(XML x)
。
因此,您可以使用它直接调用XML服务并等待响应,也可以传入将与响应XML一起调用的函数。
该函数根据参数的数量(3为异步)确定是异步还是同步,然后仅使用XMLHttpRequest对象将XML POST到URL。
我们设置了两个HTTP标头-SOAPAction和Content- xmlhttp.send(xml.toString())
,然后使用xmlhttp.send(xml.toString())
发送信封参数。
如果调用是异步的,则它将等待,直到readyState
为4(完成),然后才使用通过响应创建的XML调用回调。
因此,使用它的代码如下:
var url = document.getElementById("url").value;
var callback = function(resp) {
alert(resp..*::getQuoteReturn);
}
execService(url, envelope, callback);
在这种情况下,我们使用异步模型。 Web浏览器在与服务器对话时通常不会阻塞,我们也不想这么做。 例如,如果我们这样做了,浏览器窗口可能最终对Windows“无响应”,提示用户将其杀死。
resp..*::getQuoteReturn
如果您不熟悉E4X,则需要花费一秒钟的时间来消化此语法。 ..
表示在树中搜索命名元素。 *::
表示任何命名空间,因此该值将是响应SOAP信封中任何命名空间中名为getQuoteReturn的任何元素的值。
实际的示例代码stockclient.html还显示了请求和响应SOAP信封。 试试看-您应该看到以下内容:
图2. stockclient.html显示请求和响应SOAP信封
stockclient.html看起来像带有提交按钮的传统Web页面,尽管它不是真的(浏览器正在查看的页面永远不会改变)。 我们以这种方式构建它,以使您了解交互。 但是,页面的真实AJAX版本要好得多。 stockclientAjax.html没有按钮。 键入时,它会自动更新股票价格。 试试看。
图3. Web页面的AJAX版本-stockclientAjax.html
现在,该页面没有按钮,而是在您停止键入后自动发出请求(在发出请求之前等待0.6秒,以便在停止时“感知”)。
从Rhino提出Web服务请求
Rhino不支持XMLHTTPRequest对象,但是不用担心。 由于Rhino在Java环境中运行,因此您可以使用Java功能来发出Web服务请求。 为了证明这一点,我们编写了XMLHttpRequest对象的简单Java实现。 Rhino允许Java程序员扩展发布Java语言JavaScript环境。 要在Rhino shell中使用XMLHttpRequest对象,只需确保e4xutils.jar位于类路径中,然后使用shell命令defineClass
将其添加到环境中:
>set classpath=.\js.jar;.\xbean.jar;.\e4xutils.jar;.
>java org.mozilla.javascript.tools.shell.Main
Rhino 1.6 release 1 2004 11 30H
js> defineClass('xmlhttp.XMLHttpRequest');
这是一个测试此脚本的简单脚本:
>test.js
defineClass("xmlhttp.XMLHttpRequest");
var xh = new XMLHttpRequest();
xh.open("GET",
"http://services.xmethods.net/soap/urn:xmethods-delayed-quotes.wsdl",
false);
xh.send(null);
var wsdl = new XML(xh.responseText);
print(wsdl..*::address.@location);
>java org.mozilla.javascript.tools.shell.Main test.js
http://64.124.140.30:9090/soap
结果是,您现在可以使用到目前为止在Mozilla和Rhino中编写的相同类型的脚本(E4X + XMLHttpRequest)。 在本文的第二部分,我们将在一些有趣的场景中使用它。
结论
到目前为止,您已经了解了如何使用E4X和Javascript发起Web服务请求。 在下一篇文章中,我们将向您展示如何使用E4X提供Web服务。
翻译自: https://www.ibm.com/developerworks/xml/library/ws-ajax1/index.html
ajax脚本下载