Javascript 在节点服务器中使用res.end()时出现问题
下面是我的server.js文件中的代码片段。运行时,我发送一个带有消息的URL,res.end()会使视图呈现一个空白页面 当我注释掉res.end()命令时,视图会显示所有消息,但浏览器会一直等待服务器响应完成的信号 我知道您可以使用res.end()并将数据放入paren中,由视图传输和渲染 我期望发生的是,如果没有参数,它将只保留视图,但是parens中的空参数显示为空视图 如何在不删除视图上的数据的情况下指示响应已完成 server.jsJavascript 在节点服务器中使用res.end()时出现问题,javascript,node.js,http,server,Javascript,Node.js,Http,Server,下面是我的server.js文件中的代码片段。运行时,我发送一个带有消息的URL,res.end()会使视图呈现一个空白页面 当我注释掉res.end()命令时,视图会显示所有消息,但浏览器会一直等待服务器响应完成的信号 我知道您可以使用res.end()并将数据放入paren中,由视图传输和渲染 我期望发生的是,如果没有参数,它将只保留视图,但是parens中的空参数显示为空视图 如何在不删除视图上的数据的情况下指示响应已完成 server.js var http = require('h
var http = require('http'),
url = require('url'),
fs = require('fs');
var messages = ["testing"];
var clients = [];
http.createServer(function(req,res) {
var url_parts = url.parse(req.url);
console.log(url_parts);
if(url_parts.pathname == '/') {
// file serving
fs.readFile('./index.html', function(err, data) {
// console.log(data);
res.end(data);
});
} else if(url_parts.pathname.substr(0,5) == '/poll'){
//polling code
var count = url_parts.pathname.replace(/[^0-9]*/,'');
console.log(count);
if(messages.length > count){
res.end(JSON.stringify({
count: messages.length,
append: messages.slice(count).join("\n")+"\n"
}));
} else {
clients.push(res);
}
} else if(url_parts.pathname.substr(0, 5) == '/msg/') {
// message receiving
var msg = unescape(url_parts.pathname.substr(5));
messages.push(msg);
while(clients.length > 0) {
var client = clients.pop();
client.end(JSON.stringify({
count: messages.length,
append: msg+"\n"
}));
}
// res.end(); //if left in, this renders an empty page, if removed,
// client keeps waiting....
}
}).listen(8080, 'localhost');
console.log('server running!');
index.html
<html>
<head>
<script src="http://code.jquery.com/jquery-1.6.4.min.js"></script>
<script>
var counter = 0;
var poll = function() {
$.getJSON('/poll/'+counter, function(response) {
counter = response.count;
var elem = $('#output');
elem.text(elem.text() + response.append);
//elem.text(counter);
poll();
});
}
poll();
</script>
</head>
<body>
<textarea id="output" style="width: 90%; height: 90%;">
</textarea>
</body>
</html>
var计数器=0;
var poll=function(){
$.getJSON('/poll/'+计数器,函数(响应){
计数器=response.count;
变量元素=$(“#输出”);
elem.text(elem.text()+response.append);
//元素文本(计数器);
poll();
});
}
poll();
我已经查看了文档,但是没有看到关于使用带有空参数的.end()方法来表示和结束而不传递要呈现的数据的任何具体内容。我在谷歌上搜索过这个,但我还没有答案。改为使用res.json({success:“true”})。原因是res.end固有地认为在关闭流之前向客户端发送了一个视图。使用res.json(),您可以发送任何通用数据,而不需要隐含视图,还可以关闭客户端和服务器端的流。Moveres.end()
insidewhile
loop
while (clients.length > 0) {
var client = clients.pop();
client.end(JSON.stringify({
count : messages.length,
append : msg + "\n"
}));
if(!clients.length) {
res.end();
}
}
我对你的问题的理解是:
index.HTML
),其中有一个textarea
,显示用户提交的所有消息。收到并显示一条消息后,它将立即发送下一条消息的请求(/poll/
)/msg/
)。当HTTP请求发送到此API时,服务器将提取消息,并将此消息返回到步骤1中发送的/poll/
index.HTML
)和对/msg/
的请求发生在同一浏览器窗口中,因此不能让node.js中/msg/
的http处理程序调用res.end()
,因为在这种情况下,浏览器窗口将呈现/msg/
请求(空白页)的http响应。实际上,你不能让res
返回200 OK,不管它返回什么数据。您也不能使res
使/msg/
请求失败(使用req.destroy()
),因为在这种情况下,浏览器窗口将呈现失败/损坏的页面,这更糟/msg/
的res
保持挂起状态。虽然它将更新index.html
,但浏览器窗口将继续等待index.html
和/msg/
响应之间的浏览器窗口资源冲突——只要使用index.html
窗口的URL栏发送/msg/
请求,只要返回响应,窗口内容(index.html
)就会被清除
一种解决方案是:使用Ajax发送/msg/
。这样,窗口资源就不会有冲突。示例代码如下所示:
<body>
<textarea id="output" style="width: 90%; height: 90%;">
</textarea>
<div>
<input type="text" id="msg">
<button type="button" onclick="submitMsg()">Submit</button>
</div>
</body>
window.submitMsg = function() {
var msg = $('#msg').val();
$.getJSON('/msg/' + msg, function(res) {
$('#msg').val('');
console.log('message sent.');
});
}
提交
window.submitsg=函数(){
var msg=$('#msg').val();
$.getJSON('/msg/'+msg,函数(res){
$('#msg').val('');
日志('消息已发送');
});
}
编辑:
另一个更简单的解决方案是:在一个浏览器窗口中打开
index.html
,在另一个浏览器窗口中打开/msg/
(使用res.end('message received successfully')
指示消息接收结果)。您能发布完整的工作代码吗?当我注释掉res.end()命令时,视图显示所有消息
,你是怎么做到的?您的代码没有显示client.end()
@abhyudit jain的任何逻辑,server.js文件的完整工作代码现在已发布在上面,提前感谢您的帮助thoughts@abhyudit-jain I添加了html文件too@shaochuancs我不明白你的评论,你能重新措辞吗?我所知道的是,如果我注释掉res.end(),消息将显示出来,但浏览器继续期望更多的数据。这是因为.JSON是一个express函数,而不是节点函数吗?我在这个应用程序中不需要Express(至少现在还不需要),只是httpI尝试了这个,与我上面的代码有相同的问题,例如,当调用/msg/message时,我可以确定它已发布,但随后被删除,可能是通过empty.end()命令。谢谢你的帮助。还有其他想法吗?我回家后得看看这个。看起来很合理。我知道当我打开多个浏览器,然后从其中一个浏览器发送消息时,其他浏览器会正确更新,这很好,但我从中发送的浏览器会被清除。@CaptainChaos您的问题解决了吗?如果是的话,也许你可以“接受”其中一个答案?我正忙着别的事情。我还没有找到答案,但还没有尝试所有推荐的方法。我将在一周左右的时间里回到这个话题。谢谢你的耐心和提醒