为什么在使用createReadStream() Node.js时浏览器会一直加载?

3

作为一个新手,我了解到createReadStream()函数比readFile()函数更具有性能优势,因为createReadStream()会分块读取和写入数据,而readFile()会先读取整个内容。因此,如果文件很大,readFile()函数可能需要更长的时间才能处理数据。因此,我选择使用以下代码创建服务器,使用createReadStream()函数。

    // Create a server with fs.createReadStream(), better performance and less memory usage.
    http.createServer( function (request, response) {
      // Parse the request containing file name
      var pathname = url.parse(request.url).pathname;

      // Create a readable stream.
      var readerStream = fs.createReadStream(pathname.substr(1));

      // Set the encoding to be UTF8.
      readerStream.setEncoding('UTF8');

      // Handle stream events --> data, end and error
      readerStream.on('data', function(chunk) {
        // Page found
        // HTTP Status: 200 : OK
        // Content Type: text/plain
        response.writeHead(200, {'Content-type': 'text/html'});

        // Write the content of the file to response body.
        response.write(chunk);

        console.log('Page is being streamed...');
      });

      readerStream.on('end', function() {
        console.log('Page is streamed and emitted successfully.');
      });

      readerStream.on('error', function(err) {
        // HTTP Status: 404 : NOT FOUND
        // Content Type: text/plain
        response.writeHead(404, {'Content-type': 'text/html'});

        console.log('Page streaming error: ' + err);
      });

      console.log('Code ends!');

    }).listen(8081);

    // Console will print the message
    console.log('Server running at http://127.0.0.1:8081/');

我的.html.txt文件包含三行短文本。启动服务器后,我通过访问http://127.0.0.1:8081/index.html来访问我的网页。一切正常,index.html的内容在浏览器上被回显。
但是在浏览器的标签上,加载器图标仍然转动,就像它正在加载约1分钟。
这在Node.js服务器中正常吗?图标是否只是持续旋转,但对服务器没有任何影响?还是我错过了什么,图标不应该持续旋转?
1个回答

3

看起来你的响应并没有结束。浏览器可能认为请求还没有完成,因此继续“加载”。

如果你在开发者控制台中查看网络选项卡,你可能会发现请求还没有完成。

你应该发送 response.end()

这个方法表示所有的响应头和正文都已经被发送给服务器;服务器应该将这个信息视为完整的消息。每个响应都必须调用 response.end() 方法。

我认为在写头之后,你应该在 readerStream.on('end' 和 readerStream.on('error' 回调函数中都调用 response.end() 。这将告诉浏览器请求已经完成,它可以停止加载操作。


谢谢!这就是解决方案!我在三个回调函数readerStream.on('data'),readerStream.on('end')和readerStream.on('error')中调用了response.end()。 - O Connor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接