#介紹node
Node.js是優秀的用於搭建可擴展服務器應用程序的平臺,其中的一些應用程序須要與已存在的網絡服務進行交互。只要這些服務是基於Rest,就不會成爲問題—由於Rest服務在node世界裏是最高級公民。若是須要使用一個soap網絡服務, google一下node-soap,或者本身動手作一個soap信封。真正的挑戰是當node須要使用soap服務時,它用的是WS-*標準(WS-安全標準,MTOM等等)。幾個月前,當我面對這一狀況時,沒能找到任何模塊幫忙。這就是我決定建Ws.js的緣由。git
<br><br> #使用代碼github
1,首先你須要安裝Ws.js模塊:npm
<pre> npm install ws.js </pre>windows
<br><br> 2,寫代碼設計模式
<pre> var ws = require('ws.js') , Http = ws.Http , Security = ws.Security , UsernameToken = ws.UsernameToken var request = '<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">' + '<Header />' + '<Body>' + '<EchoString xmlns="http://tempuri.org/">' + '<s>123</s>' + '</EchoString>' + '</Body>' + '</Envelope>' var ctx = { request: request , url: "http://service/security" , action: "http://tempuri.org/EchoString" , contentType: "text/xml" } var handlers = [ new Security({}, [new UsernameToken({username: "yaron", password: "1234"})]) , new Http() ] ws.send(handlers, ctx, function(ctx) { console.log("response: " + ctx.response); }) </pre>安全
<br> 咱們來分析一下這個示例。下面的代碼引入了相關的模塊: <pre> var ws = require('ws.js') , Http = ws.Http , Security = ws.Security , UsernameToken = ws.UsernameToken </pre>服務器
<br><br> 下面幾行定義了soap信封和一些須要的信息好比url。注意:咱們須要建帶外數據的soap—由於Ws.js不是soap引擎。但一般這很容易,就如同咱們有一個工做的soap實例同樣。網絡
<pre> var request = '<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">' + '<Header />' + '<Body>' + '<EchoString xmlns="http://tempuri.org/">' + '<s>123</s>' + '</EchoString>' + '</Body>' + '</Envelope>' var ctx = { request: request , url: "http://service/security" , action: "http://tempuri.org/EchoString" , contentType: "text/xml" } </pre>app
<br><br> 以後的幾行是ws-*的核心。咱們在請求裏定義本身想要使用的協議,這個特定的請求使用ws-安全標準,並對其進行配置來發送一個象徵的用戶名。
<pre> var handlers = [ new Security({}, [new UsernameToken({username: "yaron", password: "1234"})]) , new Http() ] </pre>
<br><br> 最後,這條代碼發送請求(使用規定的協議)並對回覆進行處理。
<pre> ws.send(handlers, ctx, function(ctx) { console.log("response: " + ctx.response); }) </pre>
<br><br> 最後的soap是這個樣子的:
<pre> <Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"> <Header> <o:Security> <u:Timestamp> <u:Created>2012-02-26T11:03:40Z</u:Created> <u:Expires>2012-02-26T11:08:40Z</u:Expires> </u:Timestamp> <o:UsernameToken> <o:Username>yaron</o:Username> <o:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">1234</o:Password> </o:UsernameToken> </o:Security> </Header> <Body> <EchoString xmlns="http://tempuri.org/"> <s>123</s> </EchoString> </Body> </pre>
<br><br> #MTOM實例
發送MTOM附件的過程似曾相識,只須要指定咱們想要發送的文件,還有它對應的指向soap元素的路徑:
<pre> //add attachment to the soap request ws.addAttachment(ctx, "request", "//*[local-name(.)='File1']", "me.jpg", "image/jpeg") var handlers = [ new Mtom() , new Http() ]; </pre>
整個示例在這兒。
<br><br> #支持的協議
如今Ws.js支持如下協議:
• MTOM
• WS-Security (只是象徵性用戶名)
• WS-Addressing (全部版本)
• HTTP(S)
<br><br> #在幕後
Ws.js用的是責任連鎖設計模式,來調用不一樣的協議。這是一種可擴展模式,任何人均可以添加新的協議實現。儘管對於soap堆棧來講是一種常見模式,但在Javascript執行卻有點小麻煩。關鍵是每一個處理程序(handler)都用一個send()和一個receive()方法,發送實際上將控制傳給了下一個處理程序,咱們給那個處理程序一個回調方法。那個回調將會調用咱們的receive(),給它傳遞內容和最初咱們獲得的回調(下游處理程序沒法獲得)。能看到下面的代碼最好了:
<pre> SecurityHandler.prototype.send = function(ctx, callback) { var self = this //actual logic here... this.next.send(ctx, function(ctx) { self.receive(ctx, callback) }) } SecurityHandler.prototype.receive = function(ctx, callback) { //optionally post processing here... callback(ctx) } var s = new SecurityHandler() s.next = new HttpHandler() s.send(ctx, function(ctx) {...}) </pre>
<br><br> 像不少node app那樣,Ws.js一樣使用一些外部模塊,特別是依靠強大的xml處理庫。正如我在這兒提到的,要發現windows上基於node.js xml parser的dom不那麼容易,最終我找到了xmldom和xpath.js。
其餘Ws.js使用的有名的庫是node-formidable和node-bufferjs,對於mime解析會有幫助。
<br><br> #Ws.js的將來
Ws.js框架正處於成長階段,將來的版本,我計劃添加更多高級安全標準,如x.509數字簽名和加密。若是你有特別請求,發郵件到個人博客。若是想提供幫助,儘管在github加入進來—這樣,Ws.js會發展很快。
<br><br> By Yaron Naveh
<br><br>