下面是我的服务器.js文件中的代码片段。运行时,我发送一个带有消息的 URL,res.end() 会导致视图呈现空白页。
当我注释掉 res.end() 命令时,视图显示所有消息,但浏览器等待并等待来自服务器的响应完成的信号。
我知道您可以使用res.end()并将数据放入parens中,由视图传输和呈现。
我期望发生的是,如果没有参数,它只会留下视图,但括号中的空参数表现为空视图。
如何在不删除视图数据的情况下指示响应已完成?
服务器.js
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!');
索引.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>
我已经查看了文档,但我没有看到任何关于使用带有空参数的 .end() 方法来表示和结束而不传递要呈现的数据的具体内容。我已经用谷歌搜索过这个,但我还没有答案。
do a res.json({success:"true"}) 代替。原因是因为 res.end 本质上认为客户端在流关闭之前被发送了视图。使用 res.json(),您可以发送任何通用数据,而无需隐含视图,也可以关闭客户端和服务器端的流。
在循环内移动res.end()
while
while (clients.length > 0) {
var client = clients.pop();
client.end(JSON.stringify({
count : messages.length,
append : msg + "n"
}));
if(!clients.length) {
res.end();
}
}
我对你的问题的理解是:
- 您有一个 HTML 页面 (
index.html
),该页面有一个显示用户提交的所有邮件的textarea
。收到并显示一条消息后,它将立即发送下一条消息的请求(/poll/<n>
)。 - 要接受用户对最新消息的输入,请打开 API (
/msg/<message>
)。当 HTTP 请求发送到此 API 时,服务器将提取消息,并将此消息返回到步骤 1 中发送/poll/<n>
。 - 但是,由于 HTML 页面 (
index.html
) 和对/msg/<message>
的请求发生在同一个浏览器窗口中,你不能让 node.js 中/msg/<message>
的 http 处理程序调用res.end()
,因为在这种情况下,浏览器窗口将呈现/msg/<message>
请求(空白页)的 HTTP 响应。实际上,无论返回什么数据,您都无法使res
返回 200 OK。您也不能使res
失败/msg/<message>
请求(使用req.destroy()
),因为在这种情况下,浏览器窗口将呈现失败/损坏的页面,情况更糟。 - 不幸的是,您无法在 node 中
res
/msg/<message>
.js也保持挂起状态。虽然它会更新index.html
,但浏览器窗口将继续等待...
问题的根本原因是:index.html
和/msg/<message>
响应之间的浏览器窗口资源冲突 - 只要使用窗口的URL栏发送/msg/<message>
请求index.html
每当其响应被发送回时,窗口内容(index.html
)将被清理。
一种解决方案是:使用 Ajax 发送/msg/<message>
。这样,窗口资源就不会发生冲突。下面列出了示例代码:
<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.');
});
}
编辑: 另一个更简单的解决方案是:在一个浏览器窗口中打开index.html
,在另一个浏览器中打开/msg/<message>
(使用res.end('message received successfully')
指示消息接收结果)。