这部分有什么问题

what is wrong in this section

app.get('/dir/:dirname', (req, res) => {
    const isFile = fileName => {
        return fs.lstatSync(fileName).isFile();
    }

    var retString = '';
    var dir = `d:\${req.params.dirname}`;
    console.log(dir);
    retString+='<table>';
    fs.readdirSync(dir).map(fileName => {
        console.log(fileName);
//retString+=`<tr><td>${dir}</td><td><a href='${path.join(dir, fileName)}>${fileName}</a></td></tr>`;
        retString+=`<tr><td>${dir}</td><td>${fileName}</td></tr>`;
    }).filter(isFile);
    retString += '</table>';
    res.send(retString);
    res.end();
});

它提供文件名,但在列表结束后出错。 我错过了什么?

您的 .map() 没有从回调中 return 获取任何信息。这意味着您将 undefined 的数组传递给 .filter(),然后尝试将 undefined 传递给 fs.lstatSync(),这会导致您的错误。


您不要同时调用 res.send()res.end(),因为 res.send() 已经结束响应,因此当您再次调用 res.end() 时,可能会导致错误。

res.end()在使用res.write()时使用,可以多次调用,不会结束响应。


此外,您的 .filter(isFile) 没有做任何有用的事情。您在过滤之前构建 HTML,然后不保存使用过滤器的结果。您需要在映射之前进行过滤,如:

fs.readdirSync(dir).filter(isFile).map(...)

下面是使用异步文件 I/O 并使用 withFileTypes 选项并插入一些错误处理的代码:

app.get('/dir/:dirname', async (req, res) => {
    try {
        let retString = '';
        // this is potentially dangerous as ANY user of this server
        // can browse anywhere on your d: drive
        const dir = `d:\${req.params.dirname}`;
        console.log(dir);
        retString += '<table>';
        let entries = await fs.promises.readdir(dir, { withFileTypes: true });
        for (let entry of entries) {
            if (entry.isFile()) {
                console.log(entry.name);
                retString += `<tr><td>${dir}</td><td>${entry.name}</td></tr>`;
            }
        }
        retString += '</table>';
        res.send(retString);
    } catch (e) {
        console.log(e);
        res.sendStatus(500);
    }
});

其他问题:

  1. 这是一个潜在的危险代码,因为它允许任何有权访问您的服务器的人在您的 d: 驱动器上不受限制地浏览他们想要的任何地方

  2. 这大概应该 return 一个完整的网页,而不仅仅是 HTML table.

谢谢 jfriend - 做到了。 我开始明白了node.js

不用担心安全问题 - 这 运行 仅适用于本地网络,在其他地方使用之前会受到限制。 我知道这个漏洞。

但也感谢您的提示,因为其他人可能需要此提醒。