0

I'm attempting to get a SOAP response from a web service without using any libraries in Node, but I'm getting nowhere with the code I have. The WSDL for the service can be found here. I've tested the request in SoapUI, and with curl in a batch file. The JavaScript:

const http = require('http')
const fs = require('fs')

const xml = fs.readFileSync('latlonzipcode.xml','utf-8')

const options = {
    hostname : 'graphical.weather.gov',
    path : '/xml/SOAP_server/ndfdXMLserver.php',
    method : 'POST',
    headers : {
    'Content-Type' : 'text/xml;charset=utf-8',
    'soapAction' : 'https://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl#LatLonListZipCode'
    }
}

var obj = http.request(options,(resp)=>{
    let data = ''
    console.log(resp.statusCode)
    console.log(resp.headers)
    resp.on('data',(chunk)=>{
        data += chunk
    })
    resp.on('end',()=>{
        console.log(data)
    })
}).on('error',(err)=>{
    console.log("Error: " + err.message)
})

obj.write(xml)
obj.end()

The SOAP envelope/XML file:

<soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ndf="https://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl">
   <soapenv:Header/>
   <soapenv:Body>
       <ndf:LatLonListZipCode soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
         <zipCodeList xsi:type="xsd:string">90210</zipCodeList>
       </ndf:LatLonListZipCode>
   </soapenv:Body>
</soapenv:Envelope>

and the .bat file - for testing:

:: curl options: -H is for Header --data allows file parameters
curl -H "soapAction: \"https://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl#LatLonListCityNames\"" -H "Content-Type: text/xml;charset=UTF-8" --data @latlonzipcode.xml https://graphical.weather.gov/xml/SOAP_server/ndfdXMLserver.php > response.xml

The response I receive from the service:

403
{ server: 'AkamaiGHost',
  'mime-version': '1.0',
  'content-type': 'text/html',
  'content-length': '320',
  expires: 'Wed, 18 Jul 2018 14:18:05 GMT',
  date: 'Wed, 18 Jul 2018 14:18:05 GMT',
  connection: 'close' }
<HTML><HEAD>
<TITLE>Access Denied</TITLE>
</HEAD><BODY>
<H1>Access Denied</H1>

You don't have permission to access "http&#58;&#47;&#47;graphical&#46;weather&#46;gov&#47;xml&#47;SOAP&#95;server&#47;ndfdXMLserver&#46;php" on this server.<P>
Reference&#32;&#35;18&#46;7fd23017&#46;1531923485&#46;f45e7526
</BODY>
</HTML>

The batch file works perfectly. Any help would be great. Thanks.

UPDATE

After Googling around I found this. So I added the header User-Agent : headerTest to my options... And finally got a response, unfortunately it was the WSDL.

Joliet
  • 105
  • 1
  • 9

1 Answers1

0

As stated in my update above, my original problem was due to not using https and that the web service was blocking requests without a User-Agent header. As for the WSDL file being returned as the response, I mistakenly used GET in my options and forgot to correct it. Finally I suspected that something was going on with writing the XML to the body and found that there was an issue - I found that answer here. Here is the corrected code:

const https = require('https')
const fs = require('fs')

const xml = fs.readFileSync('latlonzipcode.xml','utf-8')

const options = {
    hostname : 'graphical.weather.gov',
    port : 443,
    path : '/xml/SOAP_server/ndfdXMLserver.php',
    method : 'POST',
    headers : {
       'User-Agent' : 'sampleTest',
       'Content-Type' : 'text/xml;charset=utf-8',
       'soapAction' : 'https://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl#LatLonListZipCode'
    }
}

var obj = https.request(options,(resp)=>{
    let data = ''
    fs.writeFile('server.log',resp.statusCode+"\n"+JSON.stringify(resp.headers),(err)=>{
        err ? console.log(err) : console.log('log file written')
    })
    resp.on('data',(chunk)=>{
        data += chunk
    })
    resp.on('end',()=>{
        fs.writeFile('soap-response.xml',data,(err)=>{
            err ? console.log(err) : console.log('data file written')
        })
        console.log(data)
    })
}).on('error',(err)=>{
    console.log("Error: " + err.message)
})

/**
 * '.write()' is not being used:
 * obj.write(xml) ? console.log('op success') : console.log('error!')
 * obj.end()
 */

obj.end(xml) ? console.log('op success') : console.log('error!')

Node.js has finally got me excited about JavaScript. Thanks.

Joliet
  • 105
  • 1
  • 9