Через три рабочих дня я наконец-то получил узел- soap для правильной работы. Я обнаружил, что при работе с Node.js часто бывает трудно найти хороший, solid, реальный пример. После десятков поисковых запросов в Интернете, множества тривиальных примеров, множества постов в блогах и т. П. Вот пример, который мне был нужен; возможно, это поможет кому-то еще.
Мне нужно вызвать функцию GetValuesForNamedID удаленной службы SOAP, и для этого мне нужно, чтобы мое сообщение SOAP выглядело так:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<h:APIAccessRequestHeader xmlns:h="urn:messages.ws.company.com/v1_4">
<Token/>
</h:APIAccessRequestHeader>
<h:ClientInfoHeader xmlns:h="urn:messages.ws.company.com/v1_4" xmlns="urn:messages.ws.company.com/v1_4">
<AppID>Helpful Example</AppID>
</h:ClientInfoHeader>
<o:Security xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<o:UsernameToken>
<o:Username>adminuser</o:Username>
<o:Password>adminpass</o:Password>
</o:UsernameToken>
</o:Security>
</s:Header>
<s:Body>
<GetValuesForNamedID xmlns="urn:messages.ws.company.com/v1_4">
<FieldName>Contact.Emails.Emaillist.Addresstype</FieldName>
</GetValuesForNamedID>
</s:Body>
</s:Envelope>
Здесь много чего происходит: есть заголовок, тело, пространство имен и аутентификация. Я могу сделать это с завязанными глазами. NET с C#, но у меня меньше опыта с Node.js. Я собираюсь оставить вам все «установки нод - soap с npm» - это все довольно просто. Я также просто собираюсь дать вам функцию JS, которая делает это и удаляет все посторонние части моего проекта, которые не имеют отношения к делу. Прочитайте комментарии для прохождения.
const soap = require('soap');
const wsdl = 'https://somesite.com/path/to?wsdl'
soap.createClient(wsdl, function(err, client) {
// arg will get passed to the function call once we finally get to that point: the tag name in
// the generated SOAP will be "FieldName" and it will have the value "Contact.Emails..."
var arg = {FieldName: 'Contact.Emails.Emaillist.Addresstype'}
// There are two SOAP header variables here. The reason I needed two is because they require
// different namespacing. We'll come back to that in a second.
var soapHeader1 = {
// This SOAP header will end up containing two elements...
// This is the first one, which creates the <APIAccessRequestHeader> element. It will have
// a <Token> element that's empty. (Why? The peculiarities of the service. Don't worry about
// it.)
APIAccessRequestHeader: {
Token : {}
},
// This is the second one, which creates the <ClientInfoHeader> element. It will have an
// <AppID> element with the value shown.
ClientInfoHeader : {
AppID : 'Helpful Example'
},
}
// Here's the second SOAP header, used for security. It'll generate an XML snippet that looks
// something like
// <Security>
// <UsernameToken>
// <Username>adminuser</Username>
// <Password>adminpass</Password>
// </UsernameToken>
// </Security>
// There'll be some namespacing and other dirt, but that's the basic idea.
var soapHeader2 = {
Security : {
UsernameToken : {
Username : 'adminuser',
Password : 'adminpass'
}
}
}
// Adding the SOAP headers. This is the step that sets the namespacing we need. I'm not sure why
// the second parameter is null, but it doesn't seem to do anything. The third parameter is the
// tag prefix (e.g. <o:Security> and <h:ClientInfoHeader>) and the fourth parameter is the URL
// that makes each prefix meaningful.
client.addSoapHeader(soapHeader1, null, 'h', 'urn:messages.ws.company.com/v1_4')
client.addSoapHeader(soapHeader2, null, 'o', 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd');
// Now we can finally call the GetValuesForNamedID function that the service exposes
client.GetValuesForNamedID(arg, function(err, result, rawResponse, soapHeader, rawRequest) {
// TODO: useful stuff
})
});