我一直在为一个项目开发基于node.js的服务器。目前,我在一个html页面上有一个脚本,它将数据发送到同一服务器上的jsp页面 - 这是有效的。但是,我似乎无法将数据发送回管道。我已经注意到各种node.js发布脚本。
编辑:我说的是JSP,我只是指标准的javascript;我只是使用.jsp扩展名而不是.js创建页面,所以我仍然可以将脚本发送为.js。编辑2:标题/执行/获取发送。它只是看起来response.write()或reponse.end()没有实际发送任何东西..我试过gzipping数据和更改transfer-encoding标头以匹配没有运气。 想想我可能会把它弄乱。
编辑3:由于某种原因,Wireshark无法检测到POST>。>
编辑4:注意到response.write()返回false。不知道如何调试。我最后会添加一些代码。
这是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);
}
});
}
有没有人对此有任何想法?
答案 0 :(得分:0)
好的,我解决了这个问题。以为我会在这里分享我的解决方案。
基本上,在添加一些inspect()调用之后,事实证明,因为reponse.write()是异步执行的,而response.end()不是,所以首先调用response.end()。这就是response.write()返回false的原因。
我通过将response.end()移动到我的异步块中来修复它。