我正在尝试使用 Express 设置特定配置,但我无法弄清楚如何使一切正常工作。我已经查看了大量关于 SO 的资源和问题,但没有骰子。我希望如果我解释了我正在尝试做的所有事情,有人能够为我指明正确的方向。
这就是我想要的:
- 对于
sub.domain.com
,执行一些逻辑并提供/public/sub/
中的静态文件; - 对于
domain.com/sub/
,将URL重写为sub.domain.com
然后继续执行与 1 中相同的逻辑; - 对于
domain.com
,从/public/
提供静态文件.
无论我做什么,我都会遇到其中一件事的问题...... 这是我当前的代码:
(根据 Stock Overflaw 的回答更新)
const baseUrl = '/bundle/cloud/public/', // This is needed as I'm hosting on NodeChef and that's their folder structure
vhost = require('vhost'), // Also tried with express-subdomain
express = require('express'),
routerMain = express.Router(),
routerSub = express.Router(),
staticOpts = { extensions: ['html', 'htm'] };
//sub.domain.com
routerSub.use((req, res, next) => {
console.log('routerSub called');
next();
});
routerSub.use(express.static(baseUrl + 'sub/', staticOpts));
// domain.com
routerMain.get('/sub', (req, res) => {
res.redirect('https://sub.domain.com/');
});
routerMain.use(express.static(baseUrl, staticOpts));
// Connect routers
app.use(vhost('sub.domain.com', routerSub));
app.use(routerMain);
结果如下:
✅ domain.com/ 🠞 /public/index.html
✅ domain.com/file 🠞 /public/file.html
✅ domain.com/sub/ 🠞 redirect to sub.domain.com/ (but then, see below)
✅ sub.domain.com/ 🠞 /public/sub/index.html
❌ domain.com/sub/file 🠞 /public/sub/file.html (should redirect to sub.domain.com/file)
当调用 sub.domain.com/时,我得到 4 个“routerSub called”日志,这是有道理的,因为有 1 个用于 html,然后 1 个用于 css,2 个用于 js,尽管有 css 和 js 文件不被阅读。
/public/sub/index.html 中的 css 标签是 <link rel="stylesheet" href="style.min.css">
,并且/public/sub/style.min.css 存在,所以我不明白为什么它找不到它。另外,我指定了扩展名,因此我不需要添加 'css'
至staticOpts
.
更新:当访问 sub.domain.com/时,css 和 js 文件没有被提供,仅仅是因为我的浏览器的缓存。/捂脸
剩下的问题是,当您尝试通过输入完整路径(如 domain.com/sub/file.html
)来访问文件时当它应该首先将您重定向到 sub.domain.com/file
时,它确实为它服务。 .
就是这样...
有人知道如何帮助解决这个问题吗? 🙏 干杯。
最佳答案
while sub.domain.com does get me /public/sub/index.html, I can't get the css and js files that are required for that page
这可能是由于staticOpts = {extensions: ['html', 'htm'] };
,您可能需要尝试添加'css', 'js'
到该列表。
I feel like it's trying to get static files from /public/
使用一些console.log
来查看调用了哪个处理程序(如果有) - 以及我之前提出的观点是否没有解决此问题。
domain.com/sub/ does not redirect at all
我认为您想使用 res.redirect
而不是 res.location
(它只设置响应 header ,而不是 HTTP 代码)。显然你不需要 next()
。
此外,我无法使此设置与router.use(subdomain('sub', routerSub))
一起使用,我认为这是因为router
本身不是包含在子域
调用中*。然而,声明 app.use
而不是 router.use
就完成了这项工作。
*:纯粹的假设,但他们使用“叠瓦式”路由器的唯一方法是当他们进行多级子域时,并且他们最后没有显示根级路由器(即没有未包装在子域
调用)。
以下是域重定向的有效且简化的模拟:
// declare stuff
const express = require('express');
const subdomain = require('express-subdomain');
const router = express.Router();
const routerSub = express.Router();
const app = express();
// make handlers to be tested
routerSub.get('/', (req, res) => {
console.log('routerSub called');
res.send('ok');
});
router.get('/', (req, res, next) => {
console.log('router called');
res.redirect('http://api.myhost.localdomain:3000');
});
// register everything properly
app.use(subdomain('api', routerSub));
app.use(router);
// start server
app.listen(3000);
我设置了 /etc/hosts
文件,其中 myhost.localdomain
和 api.myhost.localdomain
指向 localhost。 (显然。)
希望这有帮助!
编辑
事实上,我只考虑了子域
的事情,忘记了路由本身。这应该有帮助:
routerMain.get(['/sub', '/sub/*'], (req, res) => {
res.redirect('https://sub.domain.com/' + (req.params[0] ? req.params[0] : ''));
});
// or, another approach easing a pass-through for the query string as well:
routerMain.get(/^(?:(\/sub\/).+|(\/sub\/?))$/, (req, res) => {
const substr = req.params[0] ? req.params[0].length : req.params[1].length;
res.redirect('https://sub.domain.com/' + req.originalUrl.substr(substr));
});
关于javascript - Express 的子域名、重定向和静态文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54812400/