首页 > 解决方案 > Express App 提供不需要的静态文件

问题描述

我有一个由 express 提供的 react 应用程序。整个应用程序包含在 public/index.html 中。

现在我的 server.js 看起来像这样:

  1 const express = require('express');
  2 const path = require('path');
  3 const port = process.env.PORT || 8080;
  4 const app = express();
  5
  6 // the __dirname is the current directory from where the script is running
  7 app.use(express.static(__dirname));
  8
  9 app.get('*', (req, res) => {
 10   res.sendFile(path.resolve(__dirname, 'public/index.html'));
 11 });
 12
 13 app.listen(port);

但是,不知何故,正在提供诸如 package.json 和 /.ssh/known_hosts 之类的文件,这些东西显然不应该可用。

我不确定为什么app.get('*', (req, res)...没有捕获所有请求,以及为什么app.use(express.static(__dirname));似乎是允许我的应用程序服务器任何静态文件的唯一配置。

我没有任何运气app.use(express.static(__dirname+'/public'));

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

或者我能找到的任何其他东西。

编辑 - -

我的项目目录如下所示:

/myproject
    package.json
    server.js
    /public
        index.html

我希望所有请求都只为 index.html 提供服务

我仍然不明白为什么

app.use('*', express.static(path.resolve(__dirname,'/public/index.html')));

不提供任何服务。

另外,为什么在上面的例子中, res.sendFile() 没有先调用 express.static() 什么都不做。如果我删除第 7 行,则不会提供任何服务。

标签: node.jsreactjsexpresssingle-page-application

解决方案


所以,永远不要这样做:

app.use(express.static(__dirname));

在您的主服务器目录中。这会暴露所有要查看的服务器文件。

express.static()用于为整个目录提供服务时,您应该创建一个仅包含供公众使用的文件的目录,然后指向express.static()该目录。

我不确定为什么 app.get('*', (req, res)... 没有捕获所有请求

因为那app.get('*', ...)是在你之后express.static(),所以如果express.static()找到匹配的文件,app.get('*', ...)甚至永远不会看到请求。它已经被处理并且路由不再继续。


一如既往express.static()地建议您应该做什么,我们需要知道您拥有的精确配置。相对于主服务器目录,您的文件系统中的公共文件在哪里,以及您打算在客户端中使用哪些 URL 来引用这些公共可用文件。


这是一个理论上的例子(因为你没有提供你的细节):

假设您有这样的文件:

/myproject
   app.js
   /public
       main.css

并且,假设您希望能够/main.css用作来自客户端的 URL。为此,您只需在 app.js 中执行此操作:

 app.use(express.static(path.join(__dirname, "public")));

在第一个示例中,您在顶级路径中提供这些静态文件,那么您必须确保这些顶级资源与您想要提供的任何实际路由之间没有命名冲突。

如果您希望客户端 URL 是/assets/main.css,那么您可以这样做:

 app.use("/assets", express.static(path.join(__dirname, "public")));

在此示例中,您必须确保/public子目录(以及它可能拥有的任何子目录)仅包含旨在可公开访问的文件。

添加公共 URL 的路径,例如/assets消除静态资产和顶级路由之间命名冲突的可能性。这可能是一件好事,因为在任何多人项目中,处理静态资产(如 CSS 文件)的人员与处理服务器路由的人员不同的情况并不少见,因此这两个主要人员不会直接知道什么名称彼此正在使用。在一个人的项目中,你当然会把它全部记在脑子里,这样可以避免意外的命名冲突。


仅供参考,我对文件夹组织的偏好更像是这样:

/myproject
   /server
       app.js
   /public
       main.css

哪些是服务器文件,哪些是公共文件,这是 100% 明显的。然后,要在 app.js 中使用 URL 提供公共文件/assets/main.css,我会这样做:

app.use("/assets", express.static(path.join(__dirname, "../public")));

从您的评论中:

我只想为所有 ('*') GET 请求提供 public/index.html 。所有其他数据来自单独的 api。似乎 res.sendFile() 不首先使用 express.static 就无法工作。上面的代码位于 server.js

如果您只想public/index.html为所有请求提供服务(where是位于publicwhere 下方的子目录app.js),则完全删除express.static()中间件。

只需在 app.js 中使用它:

app.get('*', (req, res) => {
    res.sendFile(path.join(__dirname, 'public/index.html'));
 });

推荐阅读