简体   繁体   English

Node.js http.request使用单个res.render表达多个请求

[英]Node.js http.request Express multiple requests with single res.render

I have successfully figured out node.js/Express code for making a single http.request to my server. 我已经成功找到了node.js / Express代码,可以对我的服务器进行单个http.request。 However, the next step is to make multiple requests which use the same res.render statement at the end. 但是,下一步是发出多个请求,这些请求最后使用相同的res.render语句。

Here is my successful working code: 这是我成功的工作代码:

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

My guess is that I have to setup several things to make this work: 我的猜测是,我必须设置一些东西才能使这项工作:

  • Another "var soapBody" with my new request (I can do this). 我的新请求中有另一个“ var soapBody”(我可以执行此操作)。
  • Another "let soapRequest" (I'm good with this too). 另一个“让soapRequest”(我也很满意)。
  • Another "soapRequest.write" statement (Again, easy enough). 另一个“ soapRequest.write”语句(再次,很容易)。
  • Split the "res.render" statement out of the specific "let soapRequest" statement and gather all the variable (this is where I'm stuck). 从特定的“ let soapRequest”语句中拆分“ res.render”语句,并收集所有变量(这就是我遇到的问题)。

My guess is that I need to use async . 我的猜测是我需要使用async However, I can't for the life of me wrap my head around how to get that "res.render" to work with async. 但是,我一生都无法解决如何使“ res.render”与异步一起工作的问题。

Here is the closest I can come to an answer. 这是我能得到的最接近的答案。 However, the "cssx" and "partitionsx" variable are not translated over to the "function complete". 但是,“ cssx”和“ partitionsx”变量不会转换为“函数完成”。 They both still show up as null. 它们都仍然显示为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',
                })
            }
        };
    });
}

Any help or suggestions would be greatly appreciated. 任何帮助或建议,将不胜感激。

OK, so the thing to remember is that there is always one request mapped to one response in HTTP. 好的,要记住的是,HTTP中始终有一个请求映射到一个响应。 So you can't send multiple requests and expect to get just one response from that. 因此,您不能发送多个请求并期望仅从中获得一个响应。

Instead, you need to have the server keep track of what's been posted (perhaps in a database on a production app), and respond to each request in turn. 相反,您需要让服务器跟踪已发布的内容(可能在生产应用程序的数据库中),并依次响应每个请求。 One way might be to respond with partial documents, or respond with other codes that indicate the submission was accepted but that you need to send another request to push more info, that sort of thing. 一种方法可能是使用部分文档进行响应,或者使用其他代码进行响应,这些代码指示已接受提交,但您需要发送另一个请求以推送更多信息,诸如此类。

But again, you can't strictly accept multiple requests without responding and then respond only after all requests are given. 但是同样,您不能严格接受多个请求而不进行响应,然后仅在给出所有请求后才响应。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在 Node.Js Express 中,“res.render”是否结束了 http 请求? - In Node.Js Express, does “res.render” end the http request? Node.js和Express.js / Jade res.render返回res.render不是函数 - Node.js & Express.js/Jade res.render returns res.render is not a function node.js-Express:将参数发送到res.render() - node.js - Express: Sending parameters to res.render() Node.js res.render()与请求不起作用 - Node.js res.render() with Request not working 在Node.js Express服务器中处理GET请求:res.render(file.ejs,data)不起作用,因为未定义数据 - Handling a GET request in Node.js Express server: res.render(file.ejs, data) not working because data is not defined Node.js和Express应用程序中res.render()和ejs.render()之间的区别是什么 - What's the difference between res.render() and ejs.render() in Node.js and Express app Node.js / Express.js-如何覆盖/拦截res.render函数? - Node.js / Express.js - How to override/intercept res.render function? 如何在node.js(Express)中使用通过res.render传递的字典 - How to use dictionaries passed via res.render in node.js (Express) Node.js和Express:加载后更新router.get和res.render对象 - Node.js and Express: Updating router.get and res.render's object after load node.js - express - res.render():将变量提供给JSON参数的正确格式? - node.js - express - res.render() : Correct format for feeding variables into the JSON parameter?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM