在Express中有哪种最佳的方法可以有条件地提供静态文件?

4
我正在构建一个应用程序,它有两个独立的部分,在前端我正在构建两个独立的Angular应用。我这样做是为了更好地划分控制访问代码库,并且不必要地给一些团队成员访问他们不需要的代码。
因此,有两个独立的应用程序,从同一个NodeJS服务器提供服务。提供的应用程序取决于用户是否已登录。如果他们是游客用户,则会得到一个版本的应用程序,如果他们是注册用户,则会得到一个特权版本的应用程序,其中包含更多功能。
如何在Express中有条件/动态地提供静态文件,以便说“如果User1是游客,请提供应用程序A,否则提供应用程序B”?

有不同的代码库。 - Aravind
@Aravind 那就取决于用户知道哪个要去了。 我希望用户是无意识的。 用户只需转到 https://sparkcryptotools.com 并获取正确的应用程序。 - CodyBugstein
@Skyler 是的,登录页面可以通过访问(或点击链接到)'/login端点来访问。 - CodyBugstein
路由器获取('/', (req, res) => { if(session.user==='xxx'){ res.sendFile(path.join(__dirname, '../frontend/views1/', 'index.html')); }else{ res.sendFile(path.join(__dirname, '../frontend/views2/', 'index.html')); } }) 像上面这样的东西行不行?我只是建议。如果你有很多静态文件,那就做不到了。 - Skyler
1
@Skyler,我认为这对于包含大量像jpg等资产的Angular应用程序不起作用。 - CodyBugstein
显示剩余5条评论
1个回答

9

如果你只需要服务一个文件(例如app-1.jsapp-2.js),那么你不需要使用express.static。你可以在一个普通的路由处理器中使用res.sendFile来处理请求,像这样:

app.get('/get-app', function(req, res) {
  if (userIsLoggedIn()) {
    res.sendFile('/path-to-logged-in-app.js')
  } else {
    res.sendFile('/path-to-logged-out-app.js')
  }
})

更多关于res.sendFile的内容请点击这里

如果您想通过express.static提供多个文件,您需要使用两个express.static中间件实例,并在其上添加另一个中间件以根据用户的登录状态修改请求URL。也许可以按以下方式进行:

// Middleware function to modify the request url based on user's status
function checkUser(req, res, next) { 
 if (userIsLoggedIn()) {
    req.url = `/app-1/${req.url}`
  } else {
    req.url = `/app-2/${req.url}`
  }

  next()
}

// Set up the middleware stack
app.use(checkUser)
app.use('/app-1', express.static(path.join(__dirname, 'app-1')))
app.use('/app-2', express.static(path.join(__dirname, 'app-2')))

关于编写自己的中间件,可以在这里了解更多。您还可以在checkUser中添加一些逻辑,仅为请求静态文件的URL(例如请求URL /assets/foo.js)添加前缀,而不是添加到请求/api/some-api-function这样的URL。

话虽如此,我对Angular不太熟悉,但建议探索其他提供登录/注销内容的方法。我假设Angular中有某些组件或“视图”概念,仅渲染“LoggedIn”或“LoggedOut”组件/视图可能更加清晰,而无需发送整个不同的“应用程序”。


谢谢你的有用提示。我认为这是一个不错的解决方案,但它需要我为其中一个应用程序拥有完全独立的端点(即我必须将一个放在 https://sparkcryptotools.com/,另一个放在 https://sparkcryptotools.com/authed)。 - CodyBugstein
1
实际上,这里提出的解决方案更好,因为它直接在Express中重写了URL。这样一来,您仍然只有一个端点,并且没有HTTP重定向导致额外的请求,两个应用程序都将通过http://yourdomain.com/get-app进行服务。将只有一个端点,这个解决方案的好处还在于对用户来说,他究竟得到了哪个应用程序是无所谓的。 - Qiong Wu
1
我删除了我的答案,选择了这个答案,因为它还满足了用户不知道重定向的要求。 - Qiong Wu
在上面的示例中,没有单独的端点。客户端始终使用相同的“req.url”发出请求,您需要添加路径段以到达适当的应用程序目录。 @CodyBugstein - Mark McKelvy

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