【问题标题】:Node server returns request only after I refresh the page节点服务器仅在我刷新页面后才返回请求
【发布时间】:2016-07-31 15:00:20
【问题描述】:

首先,这是我的第一个 Node 应用程序,如果这个问题很愚蠢,我很抱歉。 所以,问题是我在访问指定的路线后尝试发送 JSON 数据。 我的代码:

var express = require('express');
var path = require('path');
var objFromFolder = require('./objFromFolder');
var app = express();
var initialTree;
var currentTree;

app.set('port', process.env.PORT || 8080);
app.set('views', __dirname + '../../views')
app.set('view engine', 'html');

app.use("/frontend", express.static(__dirname + '/../frontend'));

app.get('/', function (req, res) {
  res.json(JSON.stringify(initialTree));
});

app.get('/:folderName', function (req, res) {
  var validPath = path.resolve(__dirname + '../../', req.params.folderName);
  objFromFolder(validPath, function(err, folderItems) {

    if (err) {
      throw err;
    }

    currentTree = folderItems.sort(function (item) {
      return !(item.isFolder);
    });
  });
  res.send(JSON.stringify(currentTree));
});

app.listen(app.get('port'), function () {
  objFromFolder(__dirname + '../../', function(err, folderItems) {

    if (err) {
      throw err;
    }

    initialTree = folderItems.sort(function (item) {
      return !(item.isFolder);
    });
  });
  console.log('Ready on port ' + app.get('port'));
});

objFromFolder模块代码:

var objFromFolder = (function () {
  var fs = require('fs');
  var path = require('path');

  var objFromFolder = function (root, returnItems) {
    var folderItems = [];

    fs.readdir(root, function (err, files) {
      if (err) {
        throw err;
      }

      var pending = files.length;

      files.forEach(function (file) {
        var filePath = path.resolve(root, file);
        var fileAsObj = {
          path: filePath,
          name: file
        };

        fs.stat(filePath, function (err, stats) {
          if (err) {
            throw err;
            return;
          }

          if (stats && stats.isFile()) {
            fileAsObj.isFolder = false;
          }

          if (stats && stats.isDirectory()) {
            fileAsObj.isFolder = true;
          }

          folderItems.push(fileAsObj);
          if (!--pending) {
            returnItems(null, folderItems);
          }
        });
      });
    });

  }

  return objFromFolder;
})();

module.exports = objFromFolder;

此应用程序的任务是将工作目录结构作为对象列表返回。因此,例如,当我访问localhost:8080/node_modules 时,我第一次看到的只是空白页面,但在我刷新页面后,服务器返回 JSON。当我访问/路由时,返回JSON,我不需要刷新页面。

附:我从objFromFolder 模块中删除了错误检查,而不是在files 变量未定义时从函数中删除return。现在/ 路由又可以正常工作了,但其他路由总是在加载中。

【问题讨论】:

    标签: json node.js express


    【解决方案1】:

    您应该检查您要扫描的文件夹是否存在。 您可以安装一个path-exists npm 模块并将您的函数包装到路径存在的检查中。

    var objFromFolder = (function() {
        var fs = require('fs');
        var path = require('path');
        var pathExists = require('path-exists');
    
        var objFromFolder = function(root, returnItems) {
            var folderItems = [];
    
            // Check the path exist
            if (pathExists.sync(root)) {
                fs.readdir(root, function(err, files) {
                    if (err) {
                        throw err;
                    }
    
                    var pending = files.length;
    
                    files.forEach(function(file) {
                        var filePath = path.resolve(root, file);
                        var fileAsObj = {
                            path: filePath,
                            name: file
                        };
    
                        fs.stat(filePath, function(err, stats) {
                            if (err) {
                                throw err;
                            }
    
                            if (stats && stats.isFile()) {
                                fileAsObj.isFolder = false;
                            }
    
                            if (stats && stats.isDirectory()) {
                                fileAsObj.isFolder = true;
                            }
    
                            folderItems.push(fileAsObj);
                            if (!--pending) {
                                returnItems(null, folderItems);
                            }
                        });
                    });
                });
            }
    
        }
    
        return objFromFolder;
    })();
    
    module.exports = objFromFolder;
    

    我还修改了您的应用,最好将 app.get 中的代码包装到单个函数中或将排序移动到您的模块中。

    var express = require('express');
    var path = require('path');
    var objFromFolder = require('./objFromFolder');
    
    var app = express();
    
    app.set('port', process.env.PORT || 8080);
    app.set('views', __dirname + '../../views')
    app.set('view engine', 'html');
    
    app.use("/frontend", express.static(__dirname + '/../frontend'));
    
    app.get('/', function (req, res) {
    
      var validPath =  path.join(__dirname, '../../');
    
      objFromFolder(validPath, function(err, folderItems) {
    
        if (err) {
          throw err;
        }
    
        var currentTree = folderItems.sort(function (item) {
          return !(item.isFolder);
        });
    
        res.send(JSON.stringify(currentTree));
      });
    
    });
    
    app.get('/:folderName', function (req, res) {
      var validPath = path.join(__dirname, '../../', req.params.folderName);
    
      objFromFolder(validPath, function(err, folderItems) {
    
        if (err) {
          throw err;
        }
    
        var currentTree = folderItems.sort(function (item) {
          return !(item.isFolder);
        });
    
        res.send(JSON.stringify(currentTree));
      });
    
    });
    
    
    
    
    var port = app.get('port');
    
    app.listen(port, function () {
      console.log('Ready on port ' + port);
    });
    

    【讨论】:

    • 我的任务是在没有任何第三方模块的情况下实现它。感谢您对代码的建议。
    【解决方案2】:

    您的objFromFolder 函数执行一些异步工作(从文件中读取等)。因此,当您将响应发送到您的 /:folderName 请求时,文件夹树尚未准备好(异步作业未完成)。 所以你必须把你的res.send(...) 放在你的回调函数中,比如:

    app.get('/:folderName', function (req, res) {
      var validPath = path.resolve(__dirname + '../../', req.params.folderName);
      objFromFolder(validPath, function(err, folderItems) {
    
        if (err) {
          console.error(err.stack);
          throw err;
        }
    
        currentTree = folderItems.sort(function (item) {
          return !(item.isFolder);
        });
    
        // here the tree is ready
        res.send(JSON.stringify(currentTree));
      });
    
      // here the function code above might not have executed yet
    });
    

    编辑

    我测试了您的应用,当我请求 /node_modules 时,请求的路径错误。所以我不得不说:

    var validPath = path.resolve(__dirname, req.params.folderName);
    

    因为我的node_modules 文件夹位于我的项目的根目录(与app.js 相同)所以__dirname 具有正确的路径。

    【讨论】:

    • 现在我收到一个错误ENOENT: no such file or directory, scandir 'E:\Projects\File-System\favicon.ico'
    • 不知道是否相关..你应该检查herehere
    • 在不更改路由的情况下重新启动服务器后,返回了 JSON,但由于同样的错误,服务器崩溃了。
    • 我用console.error(err.stack); 更新了我的答案我认为objFromFolder 代码有问题。也许this 可以提供帮助
    • console.error(err.stack); 只是显示相同的错误:(
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-01-09
    • 1970-01-01
    • 1970-01-01
    • 2014-05-14
    • 2014-11-16
    • 2013-12-12
    • 1970-01-01
    相关资源
    最近更新 更多