在Node.js环境中开发新的节点时,通常倾向于使用EST web services。同时,也经常需要在Node应用中调用现有的Web服务。当涉及到调用WCF Web服务时,由于WCF支持许多标准和协议,这可能会成为一个挑战,因为这些标准和协议在Node.js中并不直接支持。幸运的是,有wcf.js这个库可以帮助简化这个过程。
可能会问,为什么需要一个特殊的库来调用SOAP Web服务。毕竟HTTP在Node.js中是一等公民,可以直接通过HTTP发送SOAP到服务。然而,Web服务可能支持Ws-Security或MTOM等标准,而Node.js默认并不支持这些。这正是另一个项目ws.js所解决的问题。
既然有了ws.js,为什么还需要wcf.js呢?这两个项目是互补的。wcf.js并没有在ws.js的基础上增加新的标准实现,而是模仿了WCF的API。这意味着用户可以使用WCF的原生API来访问WCF,而不需要学习新的范式。所有这些都是用纯JavaScript实现的!
首先,需要安装wcf.js模块:
npm install wcf.js
然后编写代码:
var BasicHttpBinding = require('wcf.js').BasicHttpBinding;
var Proxy = require('wcf.js').Proxy;
var binding = new BasicHttpBinding({
SecurityMode: "TransportWithMessageCredential",
MessageClientCredentialType: "UserName"
});
var proxy = new Proxy(binding, "http://localhost:7171/Service/clearUsername");
var message = "
如果觉得上面的代码很熟悉,那么是对的——它与WCF API相同。因此,可以自由地创建绑定和行为,就像在使用WCF一样。上面的示例在这一行初始化了一个wcf basicHttpBinding:
binding = new BasicHttpBinding({ SecurityMode: "TransportWithMessageCredential", MessageClientCredentialType: "UserName" });
然后配置凭据:
proxy.ClientCredentials.Username.Username = "yaron";
proxy.ClientCredentials.Username.Password = "1234";
然后调用服务:
proxy.send(message, "http://tempuri.org/IService/GetData", function(response, ctx) { ... });
就像使用WCF一样!
同样的方法可以帮助构建自定义绑定:
var CustomBinding = require('wcf.js').CustomBinding;
var MtomMessageEncodingBindingElement = require('wcf.js').MtomMessageEncodingBindingElement;
var HttpTransportBindingElement = require('wcf.js').HttpTransportBindingElement;
var Proxy = require('wcf.js').Proxy;
var fs = require('fs');
var binding = new CustomBinding([
new MtomMessageEncodingBindingElement({ MessageVersion: "Soap12WSAddressing10" }),
new HttpTransportBindingElement()
]);
var proxy = new Proxy(binding, "http://localhost:7171/Service/mtom");
var message = '
在这里需要注意的是自定义绑定上定义的通道:
binding = new CustomBinding([...]);
可以创建自己的通道并将它们放入管道中。这个特定的例子使用了mtom通道。
上面的例子使用了MTOM通道。这就是为什么需要做一些额外的工作,通过指定base64元素路径:
proxy.addAttachment("//*[local-name(.)='File1']", "me.jpg");
在WCF中不需要这样做,为什么Wcf.js需要这样做呢?让看看这个soap元素:
如果未使用MTOM,那么这部分将填充me.jpg的base64表示:
需要告诉MTOM通道,将这个内容放到消息之外作为二进制有效载荷。那么为什么WCF不需要告诉它这个信息呢?WCF是一个完整的soap栈,它还根据WSDL生成代理。当WCF生成File1参数时,它将其标记为MTOM转换的候选。所以Wcf有这个信息来自Wsdl。由于Wcf.js是一个纯ws-*栈(而不是soap栈),它没有访问Wsdl,需要提供这个信息。