首页 > 解决方案 > 如果我将 express.static 包装在一个函数中,服务器将停止工作

问题描述

下面的代码有效:

var express = require('express');
var path  = require('path');
var app = express();
app.use('/public', express.static("./public"));
app.listen(3000, function () {
    console.log('Example app listening on port 3000!');
});

但如果我改变app.use这样的:

var express = require('express');
var path  = require('path');
var app = express();
app.use('/public', function(){express.static("./public")}); 
// browser error "cannot GET /
app.listen(3000, function () {
    console.log('Example app listening on port 3000!');
});

为什么?服务器似乎没有发现任何错误

标签: node.jsexpress

解决方案


express.static()调用时返回一个中间件函数。您必须将该特定返回的函数传递给app.use(). 您不只是要求express.static()每个请求。您调用它一次,获取返回的函数并将其注册为中间件,app.use()然后将在每个请求上调用该中间件函数。


当你这样做正确的方式是这样的:

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

就像这样做:

const fn = express.static("./public");
app.use('/public', fn);

甚至像这样:

const fn = express.static("./public");
app.use('/public', function(req, res, next) {
    fn(req, res, next);
});

希望你能看到这段代码:

app.use('/public', function(){express.static("./public")}); 

与任何正确的解决方案都不一样。这会调用express.static()每个请求,并且永远不会调用为给定请求执行实际工作的返回函数。


想像express.static("./public")一个工厂函数。它创建了一个中间件函数,然后您将其传递给app.use()或调用您自己reqresnext作为参数。

为什么?服务器似乎没有发现任何错误

执行app.use('/public', function(){express.static("./public")});不是你想要的,但它也不会产生错误。它所做的只是在每个请求上创建一个新的中间件函数(您忽略它)。它也从不调用next让任何其他请求处理程序处理请求,因此您的服务器会卡在每个请求上,但它实际上从未导致明显的错误。

它本质上在功能上等同于:

app.use('/public', function(req, res, next) {
   // do nothing, just causes the request to get stuck since
   // the request is not handled (no response is sent)
   // and next is never called
});

请求永远不会被处理,也永远不会调用 next 来推进到其他路由处理程序,因此请求只会卡住并最终超时。


推荐阅读