简体   繁体   中英

How to consume MTOM SOAP web service in node.js?

I need to download or process a file from a soap based web service in node.js. can someone suggest me on how to handle this in node.js

I tried with 'node-soap' or 'soap' NPM module. it worked for normal soap web service. But, not for binary steam or MTOM based SOAP web service

I want to try to answer this... It's quite interesting that 2 years and 2 months later I can not figure it out how to easily solve the same problem.

I'm trying to get the attachment from a response like:

...

headers: { 'cache-control': 'no-cache="set-cookie"', 'content-type': 'multipart/related;boundary="----=_Part_61_425861994.1525782562904";type="application/xop+xml";start="";start-info="text/xml"',

...

body: '------=_Part_61_425861994.1525782562904\\r\\nContent-Type: application/xop+xml; charset=utf-8; type="text/xml"\\r\\nContent-Transfer-Encoding: 8bit\\r\\nContent-ID: \\r\\n\\r\\n....\\r\\n------=_Part_61_425861994.1525782562904\\r\\nContent-Type: application/octet-stream\\r\\nContent-Transfer-Encoding: binary\\r\\nContent-ID: \\r\\n\\r\\n PNG\\r\\n\\\n\\\\\rIHDR\\\,\\\ \\b\\\u0........binary....

I tried ws.js but no solution.

My solution:

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.');

    })

I am not sure it will works in most of the cases. It looks like unstable code to my eyes and so I'm looking for something better.

Use ws.js

Here is how to fetch the file attachments:

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)
})

Two limitations:

.

xpath = "//*[@href='cid:" + encodeURIComponent(id) + "']//parent::*"

with:

xpath = "//*[@href='cid:" + id + "']//parent::*"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM