问题场景
我司有一套金蝶的EAS系统,采用古老的WebService服务(JAVA调用很方便,可自行绕道),
由于我们的中间件采用的Nodejs实现,故此在调用WS服务时没有发现API说明如何添加WSDL头信息.
解决方案
- 1 引用 soap 组件. npm install soap --save-dev
- 2 修改源码
代码
调用代码,这里正常调用,特别注意我们header对象是如何使用的
const soap = require('soap');
//发送webSocket请求
function send(url,method,header,params,success,error){
if(header) params["_headers"] = header;
soap.createClient(url,options,(e, client) => {
if(e) error(e); return;
client[method](params, (e, res) => {
if(e) error(e); return;
success(res);
})
}
}
//以下内容是 soap 的部分源代码
//文件目录 ${ProjectPath}\node_modules\soap\lib\client.js
//发送请求的方法: Client.prototype._invoke ;行号:213
Client.prototype._invoke = function (method, args, location, callback, options, extraHeaders) {
var _this_1 = this;
var name = method.$name;
var input = method.input;
var output = method.output;
var style = method.style;
var defs = this.wsdl.definitions;
var envelopeKey = this.wsdl.options.envelopeKey;
var ns = defs.$targetNamespace;
var encoding = '';
var message = '';
var xml = null;
var req;
var soapAction;
var alias = utils_1.findPrefix(defs.xmlns, ns);
var headers = {
'Content-Type': 'text/xml; charset=utf-8'
};
//这里我们要把刚才放进Params的Headr拿出来,
//并且恢复原有的Params参数,ws服务的参数是要验证的,不能多也不能少
//=========关键代码========== S
//1 headstr 内容封装
let headstr = "";
if(args['_headers'] && Array.isArray(args['_headers'])){
headstr = '<soap:Header>';
args['_headers'].forEach(ns => {
headstr += ns;
})
headstr += ''
headstr += '</soap:Header>';
}
//2 params还原
delete args['_headers'];
//=========关键代码========== E
var finish = function (obj, body, response) {
//....省略源码显示
}
var parseSync = function (body, response) {
//....省略源码显示
}
//...省略大约50行
//下列源码主要是在封装xml文件
xml = '<?xml version="1.0" encoding="utf-8"?>' +
'<' + envelopeKey + ':Envelope ' +
xmlnsSoap + ' ' +
'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ' +
encoding +
this.wsdl.xmlnsInEnvelope + '>' +
((decodedHeaders || this.security) ?
('<' + envelopeKey + ':Header>' +
(decodedHeaders ? decodedHeaders : '') +
(this.security && !this.security.postProcess ? this.security.toXML() : '') +
'</' + envelopeKey + ':Header>')
:
'') +
'<' + envelopeKey + ':Body' +
(this.bodyAttributes ? this.bodyAttributes.join(' ') : '') +
(this.security && this.security.postProcess ? ' Id="_0"' : '') +
'>' +
message +
'</' + envelopeKey + ':Body>' +
'</' + envelopeKey + ':Envelope>';
if (this.security && this.security.postProcess) {
xml = this.security.postProcess(xml, envelopeKey);
}
if (options && options.postProcess) {
xml = options.postProcess(xml);
}
//这里我们要把head信息加入到xml里面,也就是body的上面
//=========关键代码========== S
let index = xml.indexOf("<soap:Body>");
let a = xml.substring(0,index);
let c = xml.substring(index);
xml = a + headstr + c;
//=========关键代码========== E
//发送源码.....
this.lastMessage = message;
this.lastRequest = xml;
this.lastEndpoint = location;
var eid = options.exchangeId || uuid_1.v4();
this.emit('message', message, eid);
this.emit('request', xml, eid);
//省略....
}