javascript - Express 的子域名、重定向和静态文件

标签 javascript node.js express

我正在尝试使用 Express 设置特定配置,但我无法弄清楚如何使一切正常工作。我已经查看了大量关于 SO 的资源和问题,但没有骰子。我希望如果我解释了我正在尝试做的所有事情,有人能够为我指明正确的方向。

这就是我想要的:

  1. 对于sub.domain.com ,执行一些逻辑并提供 /public/sub/ 中的静态文件;
  2. 对于domain.com/sub/ ,将URL重写为sub.domain.com然后继续执行与 1 中相同的逻辑;
  3. 对于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.localdomainapi.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/

相关文章:

javascript - 将服务器端渲染添加到使用 create-react-app 创建的现有 React 站点

javascript - 日期格式的正则表达式 - Javascript 中的 dd-mm-yyyy

javascript - 在 WebSocket.send() 之后修改缓冲区是否安全?

node.js - 尝试react-paypal-express-checkout时npm安装错误

node.js - 用户与 Mongoose 的完美匹配

javascript - Azure 应用服务中的 process.env.NODE_ENV 在哪里

javascript - Python selenium 复选框元素单击

node.js - 如何使用 AWS Lambda 生成带有自定义字体的 PDF?

node.js - 使用 Node.js/Express 提供 HTML 来构建简单的 SPA

node.js - BigQuery Node.js API startQuery 不会将数据注入(inject)到目标表中