NodeJS 路由是相对的还是根相对的取决于用户代理

NodeJS routing is relative or root-relative depending on user agent

我有一个带有此路由的 NodeJS 服务器:

require('log-timestamp');

router.get('/home', async (req, res) => {
  console.log(req.originalUrl, " :: ", req.get('User-Agent'));
  console.log("Home: /home");
  res.render('home');
});

router.get("//home", (req, res) => {
  console.log("Buggy: //home");
  res.redirect("/home");
});

router.get("/", async (req, res) => {
  console.log(req.originalUrl, " :: ", req.get('User-Agent'));
  console.log("Here: /");
  res.redirect("/home");
});

行为因用户代理而异。如果我在 Whatsapp 上共享网站的根目录,日志显示 NodeJS 复合路由并使它们相对于前一个路由(/,然后 //home,然后 //home/home,然后 404):

[2020-12-19T13:18:51.159Z] /  ::  WhatsApp/2.2049.10 N
[2020-12-19T13:18:51.161Z] Here: /
GET / 302 7.251 ms - 27
[2020-12-19T13:18:51.412Z] Buggy: //home
GET //home 302 1.731 ms - 27
[2020-12-19T13:18:51.656Z] //home/home  ::  WhatsApp/2.2049.10 N
GET //home/home 404 435.474 ms - 6592
GET /images/logo_400x400_whatsapp_shared_image_EN.png 200 2.909 ms - 36671

如果我在浏览器中打开网站的根目录,日志显示 日志显示 NodeJS 使用相对于站点根目录的每个路由(/,然后是 /home):

[2020-12-19T13:22:12.745Z] /  ::  Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:84.0) Gecko/20100101 Firefox/84.0
[2020-12-19T13:22:12.746Z] Here: /
GET / 302 1.476 ms - 54
[2020-12-19T13:22:12.893Z] /home  ::  Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:84.0) Gecko/20100101 Firefox/84.0
[2020-12-19T13:22:12.927Z] Home: /home

该行为并不严重,因为 Whatsapp 只需要共享图像,而 404 页面确实包含该图像。

为什么会这样?我该如何解决?

浏览器包括 converting relative URLs like /home or ./img/logo.png to their absolute equivalents. Like https://example.com/home or https://example.com/home/img/logo.png. That relative-to-absolute conversion is based on the page's Base URL 的方式。默认基础 URL 是 document.href,显示页面的绝对值 URL。

浏览器从绝对 URL 发出请求。查看 devtools 的 Network 选项卡以了解其工作原理。浏览器可以做到这一点,因为它们从所呈现页面的上下文中解释超链接。

嵌入其他地方的超链接没有可用的那种基础 URL 上下文。所以相对的 URLs 不能转换成绝对形式。因此,非浏览器用户代理中嵌入的URL必须是绝对的。您的网络服务器(nodejs程序)无法修复它们。

处理重定向也是浏览器的一项功能。像 WhatsApp 这样的非浏览器用户代理并不总是有接受和应用重定向的必要代码。