0

我一直在为一个项目开发基于 node.js 的服务器。目前,我在 html 页面上有一个脚本,该脚本将数据发布到同一服务器上的 jsp 页面 - 这很有效。但是,我似乎无法将数据发送回管道。我已经注意到各种 node.js 发布脚本也是如此。

编辑:我说 JSP,我只是指标准的 javascript;我刚刚制作了带有 .jsp 扩展名而不是 .js 的页面,所以我仍然可以将脚本作为 .js 发送。

编辑 2:标题 /do/ 被发送。看起来 response.write() 或 reponse.end() 并没有真正发送任何东西。我尝试压缩数据并更改传输编码标头以匹配但没有运气。想我可能会对其进行wireshark。

编辑 3:Wireshark 由于某种原因无法检测到 POST >.>

编辑 4:注意到 response.write() 返回错误。不知道如何调试。我将在最后添加更多代码。

这是 JSP 页面的代码。

/**
 * This POST parser takes XML data and translates it as follows..
 * 
 * XML -> JS Object -> XML
 * 
 * This is so I can test some libraries.
 */

// Eyes, to inspect variables
var inspect = require('eyes').inspector({maxLength: false});

// This is an XML parser, that parses XML into standard JS arrays
var xml2js = require('xml2js');

// This one converts JSON (Or JS objects) to XML.
var jsontoxml = require('jsontoxml');

exports.seperateHeader = false; // We have no separate header function
exports.separateEnd = true;

exports.GET = function(query, request, response) { // Our GET function.

    response.writeHead(200, { // Write the header
        'Content-Type': 'text/plain; charset=utf-8'
    });

    response.end("No POST data here!"); // Tell the user that there was no POST data.
}

exports.POST = function(query, postdata, request, response) { // Out POST function.

    var rootnode = undefined;
    var realdata = undefined;
    var result = undefined;

    if( postdata["data"].startsWith("<?xml") ) // It's XML, parse it
    {
        console.log("      | Detected XML.");
        var parser = new xml2js.Parser(); // Create an XML parser
        parser.parseString(postdata["data"], function (err, data) { // Parse the XML from the POST data
            if(err){
                inspect(err); // If we have an error, inspect it with eyes
            }
            else
            {
                // inspect(result); // Removed; printed the XML data as an array

                for (var prop in data) { // Get the root node of our XML; this is the command
                    rootnode = prop;
                    break;
                }

                realdata = data[rootnode]; // Get the data without the root node
                result = data;
            }
        });
    }
    else // Try to parse it as JSON
    {
        console.log("      | Detected JSON.");
        result = JSON.parse(postdata["data"]);
        for (var prop in result) { // Get the root node of our JSON; this is the command
            rootnode = prop;
            break;
        }

        realdata = result[rootnode]; // Get the data without the root node
    }
    console.log("      | Before: ")
    inspect(postdata["data"]); // Inspect the data we've got (XML or JSON)
    console.log("      | Native object: ")
    inspect(result); // Inspect the data that's been parsed to an object
    console.log("      | XML: ")
    xmldata = jsontoxml.obj_to_xml(result) // Object -> XML
    xmldata = '<?xml version="1.0" encoding="UTF-8"?><Request>' + xmldata + "</Request>"; // WUPOS extra XML stuff and the XML header
    inspect(xmldata); // Inspect the XML created from the object

    response.writeHead(200, { // Write the header
        'Content-Type':   'text/plain; charset=utf-8',
        'Content-Length': xmldata.length
    });

    response.write(xmldata); 
}

这是http响应的内部代码..

var fs = require('fs');
var url = require('url');
var path = require('path');
var querystring = require("querystring")

var ext = require("./ext.js").ext // For getting MIME types (I know, there's another module for this)

// Logging function
function Log(message, prefix, isSecure)
{
    if (!prefix)
    {
        prefix = "     ";
    }
    else
    {
        if (isSecure)
        {
            prefix = "HTTPS";
        }
        else
        {
            prefix = "HTTP ";
        }
    }

    console.log(prefix + " | " + message);
}

exports.Log = Log;

// httpRequest; this function serves standard HTTP requests
function httpRequest(request, response, isSecure) {
    request.setEncoding('utf-8'); // Set the encoding
    requrl = url.parse(request.url, true); // Parse the URL
    reqhost = request.connection.address();// Get the IP and port of the user

    if (requrl.pathname == "/") // If they were requesting the root..
    {   
        if (path.existsSync("../html/index.jsp")) // If index.jsp exists..
        {   
            reqfile = "/index.jsp"; // Remember that we want that file
        }
        else // Otherwise, index.html
        {
            reqfile = "/index.html"; 
        }
        // Log it
        if (requrl.search) { 
            Log( 
                "[" + reqhost.address + ":" + reqhost.port + "] " + request.method + " " + reqfile + requrl.search + " (Redirected from \"/\")", 
                true, isSecure
            ); 
        }
        else { 
            Log( 
                "[" + reqhost.address + ":" + reqhost.port + "] " + request.method + " " + reqfile + " (Redirected from \"/\")", 
                true, isSecure
            ); 
        }
    }
    else // If not,
    {   // Log it,
        Log( 
            "[" + reqhost.address + ":" + reqhost.port + "] " + request.method + " " + requrl.href
            , true, isSecure
        );
        reqfile = requrl.pathname; // Remember which file was requested
    }



    if (reqfile.endsWith(".jsp")) { // If the file is a JS page
        try { // Try..
            reqjs = require("../html/" + reqfile); // ..to import the code from our script
            if (reqjs.separateHeader) { // If the script has a separate function for sending the header..
                reqjs.headers(request, response); // Send it
            }
            if (request.method == 'GET') // If we have a GET
            {
                reqjs.GET(requrl.query, request, response); // Run the script's GET function
            }
            else if (request.method == 'POST') // If we have a POST
            {
                // Grab all the POST data
                var fullBody = '';

                request.on('data', function(chunk) {
                    if(fullBody.length > 1e6) // If we're getting a massive amount of data, kill the connection
                    {
                        Log("POST flood attack / faulty client detected. Connection closed.", false, isSecure);
                        request.connection.destroy();
                        return;
                    }
                    fullBody += chunk.toString();
                });

                request.on('end', function() {
                    var postdata = querystring.parse(fullBody); // Parse the POST data
                    if (reqjs.POST) // If the script has a POST function,
                    {
                        reqjs.POST(requrl.query, postdata, request, response); // Call it
                    }
                    else
                    {   // Otherwise, just call the GET function
                        reqjs.GET(requrl.query, request, response);
                    }
                });
            }
        }
        catch(e) // If there's an error..
        {
            response.writeHead(500, {
                'Content-Type': 'text/plain'
            });
            response.write("Error: " + e); // Send it to the browser
            Log("Error: " + e, false, isSecure); // Log it
        }
        response.end(); // Finish the response
    }
    else // If the file is not a JS page,
    {
        fs.readFile("html" + reqfile, function(err, data) { // Read the file in
            if(err) { // If there's an error..
                errortype = err.message.split(",")[0]; // ..get the error's code
                if (errortype == "ENOENT") // File not found
                {
                    response.statusCode = 404;
                    response.end("File not found: " + reqfile); // Send them a 404
                    Log("File not found.", false, isSecure); // Log it
                }
                else if (errortype == "EISDIR") // File is actually a directory
                {   
                    if (path.existsSync("html" + reqfile + "/index.jsp")) // If there's an index.jsp file here..
                    {   // Redirect the browser
                        Log("Found index.jsp", false, isSecure);
                        response.writeHead(301, "Moved Permanently", {
                            "Location" : reqfile + "/index.jsp"
                        });
                        response.end("<a href=\"" + reqfile + "/index.jsp" + "\">Please click here.</a>") 
                        return; // Return, so we don't have to wrap the next section of code in braces
                    }
                    else if (path.existsSync("html" + reqfile + "/index.html")) // Or, if there's an index.html file here..
                    {   // Redirect the browser
                        Log("Found index.html", false, isSecure);
                        response.writeHead(301, "Moved Permanently", {
                            "Location" : reqfile + "/index.html"
                        });
                        response.end("<a href=\"" + reqfile + "/index.html" + "\">Please click here.</a>")
                        return; // Return, so we don't have to wrap the next section of code in braces
                    }
                    // If we don't have those files, list them
                    Log("Listing files in html/"+reqfile, false, isSecure); // Log it

                    response.statusCode = 200; // Use Node.js's standard "OK" header
                    // Write out some HTML
                    response.write("<html><head></head><body>\n");
                    response.write("<h1>Directory listing: " + reqfile + "</h1>\n");
                    response.write("<ul>\n");
                    // List off the files
                    var filelist = fs.readdirSync("html" + reqfile);

                    // For every file..
                    for (element in filelist)
                    {
                        // Compile some HTML
                        var datastr = "";
                        datastr += "<li>";
                        datastr += "<a href=\"" + reqfile + "/" + filelist[element] + "\">";
                        if (filelist[element].endsWith(".jsp") || filelist[element].endsWith(".html"))
                        {   // If it ends in html or js, it's a normal page, so colour it green
                            datastr += "<span style=\"color: green;\">";
                            datastr += filelist[element];
                            datastr += "</span></a>";
                        }
                        else
                        {   // Otherwise, just put it in the list
                            datastr += filelist[element];
                            datastr += "</a>";
                        }

                        datastr += "</li>\n";
                        response.write(datastr); // Write out the HTML and go around again
                    }
                    response.end("</ul></body></html>"); // Finish the response
                }
                else
                {   // There was some other problem when opening the file
                    Log("Could not open file: " + err, false, isSecure); // Log it
                    response.statusCode = 501 // Internal server error code
                    response.end("Could not open file: " + err.message); // Tell the browser
                }
            }
            else
            {   // No problems or anomalies. Serve it!
                var contenttype = ext.getContentType(ext.getExt(reqfile).replace(".", "")); // Get the MIME type
                Log("Content-Type: " + contenttype, false, isSecure); // Log it
                response.writeHead(200, "OK", {
                    'Content-Type': contenttype
//                  'Access-Control-Allow-Origin': 'http://b.localhost:25566',
//                  'Access-Control-Allow-Methods': 'POST, GET',
//                  'Access-Control-Allow-Headers': 'Content-Type'
                });
                response.write(data); // Send the data (TODO: Send in chunks?)
                response.end() // End
            }
        });
    }
}

exports.httpRequest = httpRequest;

以及html页面的代码..

<html>

<head>
    <title>JS test A</title>
    <script src="js/jquery.js"></script>
</head>

<body style="margin-left: 30%; margin-right: 30%;">
    <div id="tests" style="float:left; width=40%;">
        <a href="#" id="a">Test A</a>
    </div>

    <div id="output" style="float:right; width=60%;">
        <form id="form">
            <textarea id="output" name="output"></textarea>
        </form>
    </div>

    <script>
        $(document).ready(function(){
            $("a#a").click(function(event){
                text = $("textarea").val();
                $("textarea").val(text + "POST test.\n");
                text = $("textarea").val();
                var http = new XMLHttpRequest();

                jsonobj = {
                    array: {
                        obj1: "obj1",
                        obj2: "obj2"
                    },
                    obj3: "obj3"
                }

                var url = "postTest3.jsp";
                var params = "data="+JSON.stringify(jsonobj);
                http.open("POST", url, true);

                //Send the proper header information along with the request
                http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");

                http.onreadystatechange = function() {//Call a function when the state changes.
                    if(http.readyState == 4 && http.status == 200) {
                        $("textarea").val(text + http.responseText);
                    }
                    else
                    {
                        $("textarea").val(text + "Repsponded: " + http.status + "\n");
                    }
                }
                http.send(params);  

            });
        });


    </script>
</body>

</html>

编辑 4:附加代码

{
                // Grab all the POST data
                var fullBody = '';

                request.on('data', function(chunk) {
                    if(fullBody.length > 1e6) // If we're getting a massive amount of data, kill the connection
                    {
                        Log("POST flood attack / faulty client detected. Connection closed.", false, isSecure);
                        request.connection.destroy();
                        return;
                    }
                    fullBody += chunk.toString();
                });

                request.on('end', function() {
                    var postdata = querystring.parse(fullBody); // Parse the POST data
                    if (reqjs.POST) // If the script has a POST function,
                    {
                        postout = reqjs.POST(requrl.query, postdata, request, response); // Call it
                        if (postout) {
                            inspect(response.write(postout, 'utf8'));
                        }
                    }
                    else
                    {   // Otherwise, just call the GET function
                        reqjs.GET(requrl.query, request, response);
                    }
                });
            }

有人对此有任何想法吗?

4

1 回答 1

0

好的,所以,我解决了这个问题。以为我会在这里分享我的解决方案。

基本上,在添加了一些 inspect() 调用之后,结果是因为 reponse.write() 是异步执行的,而 response.end() 不是,所以首先调用 response.end()。这就是 response.write() 返回 false 的原因。

我通过将 response.end() 移动到我的异步块中来修复它。

于 2012-06-07T11:30:27.553 回答