在节点服务器中使用res.end()时遇到问题

时间:2017-04-14 03:35:58

标签: javascript node.js http server

所以,下面是我的server.js文件的代码片段。运行时,我发送带有消息的URL,res.end()会导致视图呈现空白页面。

当我注释掉res.end()命令时,视图会显示所有消息,但浏览器会等待并等待服务器响应完成的信号。

我知道你可以使用res.end()并将数据放入parens中,由视图传输和呈现。

我期望发生的事情是,没有args,它只会留下视图,但是parens中的空args表现为空视图。

如何在不删除视图数据的情况下指示响应是否完整?

server.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!');

的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>

我查看了文档,但是我没有看到任何具体的使用.end()方法和空args来表示和结束而不传递要呈现的数据。我用谷歌搜索了这个,但我还没有答案。

3 个答案:

答案 0 :(得分:0)

改为执行res.json({success:“true”})。原因是因为res.end固有地认为客户端在流被关闭之前被发送了一个视图。使用res.json(),您可以发送任何通用数据,不需要隐含的视图,也可以在客户端和服务器端关闭流。

答案 1 :(得分:0)

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

答案 2 :(得分:0)

我对你的问题的理解是:

  1. 您有一个HTML页面(index.html),其中textarea显示用户提交的所有邮件。收到并显示一条消息后,它会立即发送下一条消息的请求(/poll/<n>)。
  2. 要接受用户输入的最新消息,请打开API(/msg/<message>)。当HTTP请求发送到此API时,服务器将提取消息,并将此消息返回到步骤1中发送的/poll/<n>
  3. 但是,由于HTML页面(index.html)和对/msg/<message>的请求发生在同一浏览器窗口中,您不能让node.js中的/msg/<message>的http处理程序调用res.end(),因为在这种情况下,浏览器窗口将呈现/msg/<message>请求的HTTP响应(空白页面)。实际上,无论返回什么数据,都无法使res返回200 OK。您无法使res失败/msg/<message>请求(使用req.destroy()),因为在这种情况下,浏览器窗口将呈现失败/损坏的页面,这更糟糕。
  4. 很遗憾,你无法让node.js中的res /msg/<message>继续等待。虽然它会更新index.html,但浏览器窗口会一直等待......
  5. 问题的根本原因是:index.html/msg/<message>响应之间的浏览器窗口资源冲突 - 只要使用/msg/<message>窗口的URL发送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')表示消息接收结果)。