【问题标题】:Serve static files and app.get conflict using Express.js使用 Express.js 服务静态文件和 app.get 冲突
【发布时间】:2018-02-09 20:07:22
【问题描述】:

我这里有这段代码:

var express = require('express')
  , http = require('http')

var app = express();
var server = app.listen(1344);
var io = require('socket.io').listen(server);


app.use(express.static(__dirname + '/public'));
app.use(express.bodyParser());
app.use(express.cookieParser());
app.use(express.session({secret: 'secret'}));


app.get('/', function(req, res){
    if(req.session){
        console.log(req.session);
    }
    console.log('ok');

});

app.get() 回调中的代码未被调用。如果我注释掉 app.use(express.static(__dirname + '/public')) 行,那么回调就会起作用。我试过改变顺序,但这就像彩票一样!我想知道这里出了什么问题。

我确信这与我缺乏关于如何调用中间件的知识有关。有人可以帮我理解这个问题吗?

基本上,我只想在提供文件和在浏览器上加载 index.html 之前执行一些逻辑。顺便说一句,将app.get() 放在app.use(express.static()) 行之前,并没有成功!

【问题讨论】:

  • 你有 public/index.html 文件吗?
  • 这就是它坏掉的原因。删除它,一切都会工作。可能有像“dir”这样的选项来禁用文件夹的索引,但我不确定
  • 但是,如果我删除 index.html 文件。将显示哪个文件。我是否必须重命名同一个文件。因为我想渲染 index.html 文件中的内容。
  • 无论您在 app.get() 中发送什么,都会显示出来。现在它正在发送 index.html 然后完成响应,所以它永远不会到达 app.get()。我不知道您要做什么,但使用 index.html 不是节点中的事情。使用模板系统。
  • 好的。所以为了呈现 index.html,我必须在 app.get() 中发送它吗?我怎样才能做到这一点?在 publc 我有 index.html 文件,其中定义了 css 和 javascript 文件。使用静态我能够加载 index.html 以及随后的其余文件。有没有推荐的其他工作流程,我是 Node.js 的新手,所以我可能会尝试模仿一些 PHP 习惯,结果一切都错了!

标签: node.js express


【解决方案1】:

你的静态文件中间件应该放在第一位。

app.use(express.static(__dirname + '/public'));
app.use(express.bodyParser());
app.use(express.cookieParser());
app.use(express.session({secret: 'secret'}));

您还应该为 app.router 添加一个用途。

app.use(express.static(__dirname + '/public'));
app.use(express.bodyParser());
app.use(express.cookieParser());
app.use(express.session({secret: 'secret'}));
app.use(app.router);

按顺序处理每个请求的中间件。因此,如果您的静态文件中有index.html,那么对yourdomain.com/ 的请求将永远不会到达app.router,因为它们将由静态文件处理程序提供服务。删除index.html,然后该请求将通过您的app.router

【讨论】:

  • 感谢您的回复。但是,如果使用 app.router 在该订单上使用 mddleware,则不会提供文件。 app.get() 中的代码被触发。我想同时执行文件服务和 app.get() 中的代码。
  • 静态中间件应该始终放在首位,因为您不需要它上面的所有中间件。例如,解析 cookie、设置会话或静态资产的用户身份验证是非常愚蠢的。
  • 好的...我明白了。我没有正确使用静态文件。我开始意识到这一点。我想删除 index.html 文件,并从服务器端呈现该文件。这是正确的做法吗?
  • 乔纳森是对的。首先放置您的静态处理程序,但从您的静态文件中删除 index.html。
  • 如果我想在不删除 index.html 的情况下访问 app.router 怎么办?有没有可能?
【解决方案2】:

将您的 index.html 文件重命名为其他名称。就是这么简单

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

app.get('/', function(req, res){
    if(req.session){
        console.log(req.session);
    }
    console.log('ok');
    res.sendfile(new_index_file);
});

【讨论】:

    【解决方案3】:

    我相信,这里有 3 个选项:

    1) 在静态中间件之前挂载app.get('/') 路由(可能使用app.router),以便它们优先。先挂载的中间件,先处理匹配的请求。

    2) 为您的静态路径使用路径前缀,例如 app.use('/static', express.static('public'));,以便从 example.com/static/... 提供静态信息

    3) 想表现得聪明一点,然后朝自己的腿开枪吗? :) 有时人们使用Accept 标头和内容协商在不同情况下从同一网址提供两种不同的内容类型。您可以让静态中间件检查 Accept 标头中的特定内容类型并处理请求,前提是请求的 Accept 标头需要正确的类型。否则,它会将处理向下传递给/ 视图。您可以在req.accepts 中自定义您的静态中间件内容协商。

    【讨论】:

      猜你喜欢
      • 2020-05-06
      • 1970-01-01
      • 2014-04-30
      • 1970-01-01
      • 2013-06-12
      • 1970-01-01
      • 2010-11-13
      • 1970-01-01
      • 2014-09-15
      相关资源
      最近更新 更多