使用Express在动态路由上提供静态文件服务

73

我希望能够像使用express.static(static_path)一样将静态文件提供给用户,但是我需要在动态路由上实现这一功能。

app.get('/my/dynamic/:route', function(req, res){
    // serve stuff here
});

这个评论中有一种解决方案的提示,但是开发者的意思并不立即清晰。


3
你尝试使用 "use" 代替 "get" 了吗:app.use('/foo',express.static(__dirname+'/yourstaticdir')) - Markis
1
我实际上希望它使用动态匹配的URL,例如/users/:id。 - Waylon Flinn
1
请查看Sencha Lab的connect框架(Express是其构建的基础),并查看其static中间件。滚动到中间件页面的底部,将源代码复制并粘贴到您的路由中。从那里开始,您可以根据需要调整它以像static中间件一样提供静态文件服务。否则,只需使用fs.readFile即可。 - Sal Rahman
4个回答

111

好的,我在 Express 的响应对象源代码中找到了一个例子(response object)。这是那个例子的略微修改版本。

app.get('/user/:uid/files/*', function(req, res){
    var uid = req.params.uid,
        path = req.params[0] ? req.params[0] : 'index.html';
    res.sendFile(path, {root: './public'});
});

它使用res.sendFile方法。

注意: 对于sendFile的安全性更改需要使用root选项。


10
不能使用'../dir/' + file,因为Express会认为这是恶意用户输入(这很好)。相反,要发送相对于某个目录的文件,请使用:`response.sendfile(file, {root: './dir/'})` - blented
但是在这种情况下如何呈现特定页面并传递页面参数,例如 res.render(page, pageParameters) - loretoparisi
这对我有用,谢谢。确保在Express中包含中间件以提供静态文件app.use(express.static("./public"));(答案中未显示)。 - chris

17

我使用以下代码为不同的URL请求相同的静态文件提供服务:

server.use(express.static(__dirname + '/client/www'));
server.use('/en', express.static(__dirname + '/client/www'));
server.use('/zh', express.static(__dirname + '/client/www'));

虽然这不是你的情况,但它可能帮助其他来到这里的人。


6
这个回答如何与URL参数的“动态”部分相符?我不明白这如何帮助他从路由(例如/user/:uid,注意冒号前的:uid)中提供静态文件。 - chamberlainpi

8
您可以使用res.sendfile 或者您仍然可以使用express.static:
const path = require('path');
const express = require('express');
const app = express();

// Dynamic path, but only match asset at specific segment.
app.use('/website/:foo/:bar/:asset', (req, res, next) => {
  req.url = req.params.asset; // <-- programmatically update url yourself
  express.static(__dirname + '/static')(req, res, next);
});         

// Or just the asset.
app.use('/website/*', (req, res, next) => {
  req.url = path.basename(req.originalUrl);
  express.static(__dirname + '/static')(req, res, next);
});

1
非常感谢,这正是我所需要的! - bugovicsb

4

这应该可以正常工作:

app.use('/my/dynamic/:route', express.static('/static'));
app.get('/my/dynamic/:route', function(req, res){
    // serve stuff here
});

文档说明了使用app.use()的动态路由有效。 请参阅https://expressjs.com/en/guide/routing.html


1
这终于是我的问题的答案。但让我想知道,如果我只有一个标准的 app.use(express.static('./public')); 中间件,为什么我们还需要为所有参数化路由添加另一个 app.use('/viewVob/:id', express.static('./public')); 中间件呢? - Matthew Wolman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接