如何在node.js中使用MTOM SOAP web服务?

如何在node.js中使用MTOM SOAP web服务?,node.js,soap-client,mtom,node.js-stream,binarystream,Node.js,Soap Client,Mtom,Node.js Stream,Binarystream,我需要从node.js中基于soap的web服务下载或处理文件。 有人能建议我如何在node.js中处理这个问题吗 我尝试使用“节点soap”或“soap”NPM模块。它适用于普通的soapweb服务。但是,不是针对二进制蒸汽或基于MTOM的SOAP web服务,我想尝试回答这个问题。。。非常有趣的是,两年零两个月后,我无法想出如何轻松解决同样的问题 我试图从如下响应中获取附件: 标题:{'cache control':'no cache=“set cookie”, “内容类型”:“多部分/相

我需要从node.js中基于soap的web服务下载或处理文件。 有人能建议我如何在node.js中处理这个问题吗


我尝试使用“节点soap”或“soap”NPM模块。它适用于普通的soapweb服务。但是,不是针对二进制蒸汽或基于MTOM的SOAP web服务,我想尝试回答这个问题。。。非常有趣的是,两年零两个月后,我无法想出如何轻松解决同样的问题

我试图从如下响应中获取附件:

标题:{'cache control':'no cache=“set cookie”, “内容类型”:“多部分/相关的;边界=“---=”第61部分“425861994.1525782562904”;type=“应用程序/xop+xml”;start=“”;start info=“文本/xml”

正文:'----=\u部分\u 61\u 425861994.1525782562904\r\n内容类型: application/xop+xml;字符集=utf-8; type=“text/xml”\r\n内容传输编码:8位\r\n内容ID: \r\n\r\n…\r\n--------=\u Part\u 61\u 425861994.1525782562904\r\n内容类型: 应用程序/八位字节流\r\n内容传输编码: 二进制\r\n内容ID: \r\n\r\n�PNG\r\n\u001a\n\u0000\u0000\u0000\rIHDR\u0000\u0000\u0002\u0000\u0000\u0005�\b\u0006\u0…….二进制

我试过了,但没有解决办法

我的解决方案:

var request = require("request");
var bsplit = require('buffer-split')

// it will extract "----=_Part_61_425861994.1525782562904" from the response
function getBoundaryFromResponse(response) {
    var contentType = response.headers['content-type']
    if (contentType && contentType.indexOf('boundary=') != -1 ) {
        return contentType.split(';')[1].replace('boundary=','').slice(1, -1)
    }
    return null
}


function splitBufferWithPattern(binaryData, boundary) {
    var b = new Buffer(binaryData),
        delim = new Buffer(boundary),
        result = bsplit(b, delim);
    return result
}


var options = {
    method: 'POST',
    url: 'http://bla.blabal.../file',
    gzip: true,
    headers: {
        SOAPAction: 'downloadFile',
        'Content-Type': 'text/xml;charset=UTF-8'
    },
    body: '<soapenv: ... xml request of the file ... elope>'
};

var data = [];
var buffer = null;
var filename = "test.png"

request(options, function (error, response, body) {
        if (error) throw new Error(error);

        if (filename && buffer) {
            console.log("filename: " + filename)
            console.log(buffer.toString('base64'))
            // after this, we can save the file from base64 ...
        }
    })
    .on('data', function (chunk) {
        data.push(chunk)

    })
    .on('end', function () {
        var onlyPayload = splitBufferWithPattern(Buffer.concat(data), '\r\n\r\n') // this will get from PNG
        buffer = onlyPayload[2]
        buffer = splitBufferWithPattern(buffer, '\r\n-')[0]
        console.log('Downloaded.');

    })
var请求=要求(“请求”);
var bsplit=require('buffer-split')
//它将从响应中提取“---=”u Part_61_425861994.1525782562904”
函数getBoundaryFromResponse(响应){
var contentType=response.headers['content-type']
if(contentType&&contentType.indexOf('boundary=')!=-1){
返回contentType.split(“;”)[1]。替换('boundary=”,“”)。切片(1,-1)
}
返回空
}
函数splitBufferWithPattern(二进制数据,边界){
var b=新缓冲区(二进制数据),
delim=新缓冲区(边界),
结果=bsplit(b,delim);
返回结果
}
变量选项={
方法:“POST”,
网址:'http://bla.blabal.../file',
gzip:是的,
标题:{
SOAPAction:“下载文件”,
“内容类型”:“text/xml;charset=UTF-8”
},
正文:“”
};
var数据=[];
var buffer=null;
var filename=“test.png”
请求(选项、功能(错误、响应、正文){
如果(错误)抛出新错误(错误);
if(文件名和缓冲区){
log(“文件名:”+filename)
console.log(buffer.toString('base64'))
//在此之后,我们可以从base64保存文件。。。
}
})
.on('data',函数(块){
数据推送(区块)
})
.on('end',函数(){
var onlyPayload=splitBufferWithPattern(Buffer.concat(数据),'\r\n\r\n')//这将从PNG获取
缓冲区=仅支付加载[2]
buffer=splitBufferWithPattern(缓冲区“\r\n-”)[0]
console.log('download');
})
我不确定它是否能在大多数情况下工作。在我看来,它像是不稳定的代码,所以我正在寻找更好的东西。

使用

以下是如何获取文件附件:

const ws = require('ws.js')
const { Http, Mtom } = ws

var handlers =  [ new Mtom(), new Http()];
var request = '<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope">' +
                '<s:Body>' +
                  '<EchoFiles xmlns="http://tempuri.org/">' +
                      '<File1 />' +
                  '</EchoFiles>' +
                '</s:Body>' +
              '</s:Envelope>'

var ctx = { request: request
          , contentType: "application/soap+xml"
          , url: "http://localhost:7171/Service/mtom"
          , action: "http://tempuri.org/IService/EchoFiles"
          }

ws.send(handlers, ctx, function(ctx) {
  //read an attachment from the soap response
  var file = ws.getAttachment(ctx, "response", "//*[local-name(.)='File1']")
  // work with the file
  fs.writeFileSync("result.jpg", file)
})
与:

(对我来说)很难说这是一个答案还是另一个问题。
xpath = "//*[@href='cid:" + encodeURIComponent(id) + "']//parent::*"
xpath = "//*[@href='cid:" + id + "']//parent::*"