Как использовать веб-сервис MTOM SOAP в node.js?
Мне нужно скачать или обработать файл из веб-службы на основе мыла в node.js. может кто-нибудь предложить мне, как справиться с этим в node.js
Я попробовал с модулем NPM "node-soap" или "soap". это работало на обычном мыльном веб-сервисе. Но не для бинарного Steam или веб-службы SOAP на базе MTOM
1 ответ
Я хочу попытаться ответить на это... Интересно, что через 2 года и 2 месяца я не могу понять, как легко решить ту же проблему.
Я пытаюсь получить вложение из ответа, например:
...
заголовки: { 'cache-control': 'no-cache="set-cookie"', 'content-type': 'multipart/related;border ="----=_Part_61_425861994.1525782562904";type="application/ ХОР + XML "начать =""; старт-инфо =" текст / XML "",
...
body: '------ = _ Part_61_425861994.1525782562904 \ r \ nContent-Type: application / xop + xml; кодировка = 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: двоичный файл \r\nContent-ID: \r\n\r\n PNG\r\n\u001a\n\u0000\u0000\u0000\rIHDR\u0000\u0000\u0002 \ u0000 \ u0000 \ u0005 \ Ь \u0006\u0........ двоичный....
Я пробовал ws.js, но не нашел решения.
Мое решение:
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.');
})
Я не уверен, что это будет работать в большинстве случаев. Это выглядит как нестабильный код для моих глаз, и поэтому я ищу что-то лучшее.
Используйте ws.js
Вот как получить прикрепленные файлы:
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)
})
Два ограничения:
- Базовая аутентификация не предоставляется из коробки, требуется патч https://github.com/yaronn/ws.js/pull/40
- Если имя файла является URL, вам необходимо применить еще один патч на mtom.js. Заменить:
.
xpath = "//*[@href='cid:" + encodeURIComponent(id) + "']//parent::*"
с участием:
xpath = "//*[@href='cid:" + id + "']//parent::*"