2017-11-14 4 views
0

Ich habe erfolgreich node.js/Express-Code zum Erstellen einer einzelnen http.Request zu meinem Server. Der nächste Schritt besteht jedoch darin, mehrere Anforderungen zu stellen, die dieselbe res.render-Anweisung am Ende verwenden.Node.js http.request Express mehrere Anfragen mit einzelnen Res.Render

Hier ist meine erfolgreiche Arbeitscode:

module.exports = function (app) { 
    // MODULES - INCLUDES 
    var xml2js = require('xml2js'); 
    var parser = new xml2js.Parser(); 

    // FORM - SUBMIT - CUCMMAPPER 
    app.post('/cucmmapper/submit', function (req, res) { 

     // FORM - DATA COLLECTION 
     var cucmpub = req.body.cucmpub; 
     var cucmversion = req.body.cucmversion; 
     var username = req.body.username; 
     var password = req.body.password; 

     // JS - VARIABLE DEFINITION 
     var authentication = username + ":" + password; 
     var soapreplyx = ''; 
     var cssx = ''; 
     var spacer = '-----'; 
     var rmline1 = ''; 
     var rmline2 = ''; 
     var rmline3 = ''; 
     var rmline4 = ''; 
     var rmbottomup1 = ''; 
     var rmbottomup2 = ''; 
     var rmbottomup3 = ''; 

     // HTTP.REQUEST - BUILD CALL 
     var https = require("https"); 
     var headers = { 
      'SoapAction': 'CUCM:DB ver=' + cucmversion + ' listCss', 
      'Authorization': 'Basic ' + new Buffer(authentication).toString('base64'), 
      'Content-Type': 'text/xml; charset=utf-8' 
     }; 

     // SOAP - AXL CALL 
     var soapBody = new Buffer('<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns="http://www.cisco.com/AXL/API/11.5">' + 
      '<soapenv:Header/>' + 
      '<soapenv:Body>' + 
      '<ns:listCss sequence="?">' + 
      '<searchCriteria>' + 
      '<name>%</name>' + 
      '</searchCriteria>' + 
      '<returnedTags uuid="?">' + 
      '<name>?</name>' + 
      '<description>?</description>' + 
      '<clause>?</clause>' + 
      '</returnedTags>' + 
      '</ns:listCss>' + 
      '</soapenv:Body>' + 
      '</soapenv:Envelope>'); 

     // HTTP.REQUEST - OPTIONS 
     var options = { 
      host: cucmpub, // IP ADDRESS OF CUCM PUBLISHER 
      port: 8443, // DEFAULT CISCO SSL PORT 
      path: '/axl/', // AXL URL 
      method: 'POST', // AXL REQUIREMENT OF POST 
      headers: headers, // HEADER VAR 
      rejectUnauthorized: false // REQUIRED TO ACCEPT SELF-SIGNED CERTS 
     }; 

     // HTTP.REQUEST - Doesn't seem to need this line, but it might be useful anyway for pooling? 
     options.agent = new https.Agent(options); 

     // HTTP.REQUEST - OPEN SESSION 
     let soapRequest = https.request(options, soapResponse => { 
      soapResponse.setEncoding('utf8'); 
      soapResponse.on('data', chunk => { 
       soapreplyx += chunk 
      }); 
      // HTTP.REQUEST - RESULTS + RENDER 
      soapResponse.on('end',() => { 

       // EDIT - SCRUB XML OUTPUT 
       var rmline1 = soapreplyx.replace(/<\?xml\sversion='1\.0'\sencoding='utf-8'\?>/g, ''); 
       var rmline2 = rmline1.replace(/<soapenv:Envelope\sxmlns:soapenv="http:\/\/schemas.xmlsoap.org\/soap\/envelope\/">/g, ''); 
       var rmline3 = rmline2.replace(/<soapenv:Body>/g, ''); 
       var rmline4 = rmline3.replace(/<ns:listCssResponse\sxmlns:ns="http:\/\/www\.cisco\.com\/AXL\/API\/[0-9]*\.[0-9]">/g, ''); 
       var rmbottomup1 = rmline4.replace(/<\/soapenv:Envelope>/g, ''); 
       var rmbottomup2 = rmbottomup1.replace(/<\/soapenv:Body>/g, ''); 
       var xmlscrubbed = rmbottomup2.replace(/<\/ns:listCssResponse>/g, ''); 
       // console.log(xmlscrubbed); 
       // console.log(spacer); 

       // XML2JS - TESTING 
       parser.parseString(xmlscrubbed, function (err, result) { 
        var cssx = result['return']['css']; 
        // console.log(cssx); 
        // console.log(spacer); 
        res.render('cucmmapper-results.html', { 
         title: 'CUCM Toolbox', 
         cucmpub: cucmpub, 
         cssx: cssx, 
         soapreply: soapreplyx, 
         xmlscrubbed: xmlscrubbed 
        }); 
       }); 
      }); 
     }); 

     // SOAP - SEND AXL CALL 
     soapRequest.write(soapBody); 
     soapRequest.end(); 
    }); 
} 

Meine Vermutung ist, dass ich die Einrichtung mehrere Dinge haben diese Arbeit zu machen:

  • Ein anderer „var soapBody“ mit meinem neuen Anfrage (I kann dies tun).
  • Ein weiteres "let soapRequest" (ich bin auch damit gut).
  • Eine weitere "soapRequest.write" Anweisung (Wieder, einfach genug).
  • Teilen Sie die "res.render" -Anweisung aus der spezifischen "let soapRequest" -Anweisung und sammeln Sie die ganze Variable (hier stehe ich fest).

Meine Vermutung ist, dass ich async verwenden muss. Jedoch kann ich nicht für das Leben von mir meinen Kopf einwickeln, wie man diesen "res.render" mit async arbeiten lässt.

Hier ist die nächste, die ich zu einer Antwort kommen kann. Die Variablen "cssx" und "partitionsx" werden jedoch nicht in die "function complete" übersetzt. Sie beide erscheinen immer noch als null.

module.exports = function (app) { 

    // MODULES - INCLUDES 
    var xml2js = require('xml2js'); 
    var parser = new xml2js.Parser(); 

    // FORM - SUBMIT - CUCMMAPPER 
    app.post('/cucmmapper/submit', function (req, res) { 

     // FORM - DATA COLLECTION 
     var cucmpub = req.body.cucmpub; 
     var cucmversion = req.body.cucmversion; 
     var username = req.body.username; 
     var password = req.body.password; 

     // JS - VARIABLE DEFINITION - GLOBAL 
     var authentication = username + ":" + password; 
     var soapreplyx = ''; 
     var cssx = null; 
     var spacer = '-----'; 
     var rmline1 = ''; 
     var rmline2 = ''; 
     var rmline3 = ''; 
     var rmline4 = ''; 
     var rmbottomup1 = ''; 
     var rmbottomup2 = ''; 
     var rmbottomup3 = ''; 
     var soapreplyp = ''; 
     var partitionsx = null; 
     var rmline1p = ''; 
     var rmline2p = ''; 
     var rmline3p = ''; 
     var rmline4p = ''; 
     var rmbottomup1p = ''; 
     var rmbottomup2p = ''; 
     var rmbottomup3p = ''; 

     // HTTP.REQUEST - BUILD CALL - GLOBAL 
     var https = require("https"); 
     var headers = { 
      'SoapAction': 'CUCM:DB ver=' + cucmversion + ' listCss', 
      'Authorization': 'Basic ' + new Buffer(authentication).toString('base64'), 
      'Content-Type': 'text/xml; charset=utf-8' 
     }; 

     // SOAP - AXL CALL - CSS 
     var soapBody = new Buffer('<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns="http://www.cisco.com/AXL/API/11.5">' + 
      '<soapenv:Header/>' + 
      '<soapenv:Body>' + 
      '<ns:listCss sequence="?">' + 
      '<searchCriteria>' + 
      '<name>%</name>' + 
      '</searchCriteria>' + 
      '<returnedTags uuid="?">' + 
      '<name>?</name>' + 
      '<description>?</description>' + 
      '<clause>?</clause>' + 
      '</returnedTags>' + 
      '</ns:listCss>' + 
      '</soapenv:Body>' + 
      '</soapenv:Envelope>'); 

     // SOAP - AXL CALL - PARTITIONS 
     var soapBody2 = new Buffer('<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns="http://www.cisco.com/AXL/API/11.5">' + 
      '<soapenv:Header/>' + 
      '<soapenv:Body>' + 
      '<ns:listRpite{artotopm} sequence="?">' + 
      '<searchCriteria>' + 
      '<name>%</name>' + 
      '</searchCriteria>' + 
      '<returnedTags uuid="?">' + 
      '<name>?</name>' + 
      '</returnedTags>' + 
      '</ns:listRoutePartition>' + 
      '</soapenv:Body>' + 
      '</soapenv:Envelope>'); 

     // HTTP.REQUEST - OPTIONS - GLOBAL 
     var options = { 
      host: cucmpub, // IP ADDRESS OF CUCM PUBLISHER 
      port: 8443, // DEFAULT CISCO SSL PORT 
      path: '/axl/', // AXL URL 
      method: 'POST', // AXL REQUIREMENT OF POST 
      headers: headers, // HEADER VAR 
      rejectUnauthorized: false // REQUIRED TO ACCEPT SELF-SIGNED CERTS 
     }; 

     // HTTP.REQUEST - GLOBAL (Doesn't seem to need this line, but it might be useful anyway for pooling?) 
     options.agent = new https.Agent(options); 

     // HTTP.REQUEST - OPEN SESSION - CSS 
     var soapRequest = https.request(options, soapResponse => { 
      soapResponse.setEncoding('utf8'); 
      soapResponse.on('data', chunk => { 
       soapreplyx += chunk 
      }); 
      // HTTP.REQUEST - RESULTS + RENDER 
      soapResponse.on('end',() => { 

       // EDIT - SCRUB XML OUTPUT 
       var rmline1 = soapreplyx.replace(/<\?xml\sversion='1\.0'\sencoding='utf-8'\?>/g, ''); 
       var rmline2 = rmline1.replace(/<soapenv:Envelope\sxmlns:soapenv="http:\/\/schemas.xmlsoap.org\/soap\/envelope\/">/g, ''); 
       var rmline3 = rmline2.replace(/<soapenv:Body>/g, ''); 
       var rmline4 = rmline3.replace(/<ns:listCssResponse\sxmlns:ns="http:\/\/www\.cisco\.com\/AXL\/API\/[0-9]*\.[0-9]">/g, ''); 
       var rmbottomup1 = rmline4.replace(/<\/soapenv:Envelope>/g, ''); 
       var rmbottomup2 = rmbottomup1.replace(/<\/soapenv:Body>/g, ''); 
       var xmlscrubbed = rmbottomup2.replace(/<\/ns:listCssResponse>/g, ''); 
       // console.log(xmlscrubbed); 
       // console.log(spacer); 

       // XML2JS - TESTING 
       parser.parseString(xmlscrubbed, function (err, result) { 
        var cssx = result['return']['css']; 
        // console.log(cssx); 
        // console.log(spacer); 
        complete(); 
       }); 
      }); 
     }); 

     // SOAP - SEND AXL CALL - CSS 
     soapRequest.write(soapBody); 
     soapRequest.end(); 

     // SOAP - SEND AXL CALL - PARTITIONS 
     var soapRequest2 = https.request(options, soapResponse2 => { 
      soapResponse2.setEncoding('utf8'); 
      soapResponse2.on('data', chunk => { 
       soapreplyp += chunk 
      }); 
      // HTTP.REQUEST - RESULTS + RENDER 
      soapResponse2.on('end',() => { 

       // EDIT - SCRUB XML OUTPUT 
       var rmline1p = soapreplyy.replace(/<\?xml\sversion='1\.0'\sencoding='utf-8'\?>/g, ''); 
       var rmline2p = rmline1.replace(/<soapenv:Envelope\sxmlns:soapenv="http:\/\/schemas.xmlsoap.org\/soap\/envelope\/">/g, ''); 
       var rmline3p = rmline2.replace(/<soapenv:Body>/g, ''); 
       var rmline4p = rmline3.replace(/<ns:listCssResponse\sxmlns:ns="http:\/\/www\.cisco\.com\/AXL\/API\/[0-9]*\.[0-9]">/g, ''); 
       var rmbottomup1p = rmline4.replace(/<\/soapenv:Envelope>/g, ''); 
       var rmbottomup2p = rmbottomup1.replace(/<\/soapenv:Body>/g, ''); 
       var xmlscrubbedp = rmbottomup2.replace(/<\/ns:listCssResponse>/g, ''); 
       console.log(xmlscrubbedp); 
       console.log(spacer); 

       // XML2JS - TESTING 
       parser.parseString(xmlscrubbedp, function (err, result) { 
        var partitionsx = result['return']['css']; 
        // console.log(partitionsx); 
        // console.log(spacer); 
        complete(); 
       }); 
      }); 
     }); 
     // SOAP - SEND AXL CALL - PARTITIONS 
     soapRequest2.write(soapBody2); 
     soapRequest2.end(); 

     // PAGE - RENDER 
     function complete() { 
      if (cssx !== null && partitionsx !== null) { 
       res.render('cucmmapper-results.html', { 
        title: 'CUCM Toolbox', 
        cucmpub: cucmpub, 
        cssx: cssx, 
        partitionsx: partitionsx, 
       }) 
      } else { 
       res.render('cucmerror.html', { 
        title: 'CUCM Toolbox', 
       }) 
      } 
     }; 
    }); 
} 

Jede Hilfe oder Vorschläge würden sehr geschätzt werden.

+0

Lassen Sie mich sicherstellen, dass mir klar ist. Sie möchten eine POST-Anfrage erhalten, dann mehrere Anfragen an einen anderen Server senden und dann die Antworten in einer Antwort auf den anfänglichen POST bündeln, ist das korrekt? – Paul

+0

@Paul, danke fürs Fragen und Lesen meiner Frage. Um dies zu verdeutlichen, möchte ich einfach mehrere POST-Anfragen an denselben Server stellen, die Antwortdaten verarbeiten und alle verarbeiteten Daten auf einer einzigen res.render-Seite anzeigen. Ist das sinnvoller? –

+0

Sortieren von. Also ist der Code hier der Server, der diese aggregierte SOAP-Antwort im Laufe mehrerer Anfragen erstellen wird? – Paul

Antwort

0

OK, so ist es wichtig zu erinnern, dass immer eine Anfrage einer Antwort in HTTP zugeordnet ist. Sie können also nicht mehrere Anfragen senden und erwarten nur eine Antwort.

Stattdessen müssen Sie den Server verfolgen lassen, was gepostet wurde (möglicherweise in einer Datenbank in einer Produktionsanwendung), und auf jede Anfrage der Reihe nach antworten. Eine Möglichkeit könnte sein, mit unvollständigen Dokumenten zu antworten oder mit anderen Codes zu antworten, die anzeigen, dass die Einreichung akzeptiert wurde, aber dass Sie eine weitere Anfrage senden müssen, um mehr Informationen zu senden, so etwas.

Aber wieder können Sie mehrere Anfragen nicht streng akzeptieren, ohne zu antworten und dann erst antworten, nachdem alle Anfragen gegeben wurden.

+0

danke für die Erinnerung. Am Ende bearbeitete ich meine Frage, um die zwei separaten HTTP-Anfragen zu zeigen, die gesendet wurden. Ich glaube, das ist der richtige Weg. Beide Anfragen (eine mit "HTTP.REQUEST - OPEN SESSION - CSS" und die andere "HTTP.REQUEST - OPEN SESSION - PARTITIONS") geben gültige Antworten zurück und ich kann Daten manipulieren. Ich kann einfach nicht herausfinden, wie man die Daten von beiden Anfragen zu dieser separaten "res.render" -Anweisung bringt. Ist das sinnvoller? –