我的 Windows Server 2022 数据中心(AWS 上的虚拟机)上有两个网站。我以一种非正统的方式设置它们。第一个位于 http://www.planetshah.com/pwv,另一个位于 http://www.planetshah.com/mixes。换句话说,它们都在同一个域下,只是由不同的路径分开。这导致了一些问题。
问题是这样的:当我访问某个文件(比如planetshah.com/pwv)时,某些文件(例如 favicon.ico 和 styles.css)的路径会缓存在浏览器中。然后,当我转到另一个(planetshah.com/mixes)时,浏览器似乎假设我需要相同的文件,因此在我输入完整的 url“planetshah.com/mixes”之前,它会联系服务器来获取它们。 com/mixes”。也就是说,一旦它识别出 URL 中的“planetshah.com”,它就会访问我的服务器并获取所述文件。我知道这一点是因为我的服务器上有控制台日志,并且在我输入完“planetshah.com”后我就看到它们打印出来。然后,当我完成 url(“planetshah.com/mixes”)并按 Enter 键时,它会获取其余部分(html 文件、javascript 文件等),但它会尝试使用其他站点中的样式和 favicon 文件,其中当然不行。
我使用 Node.js 和 Express 运行服务器,并使用 Bouncy(一个 npm 包)将请求重新路由到适当的端口(我想要访问的特定站点正在运行)。代码如下所示:
const bouncy = require('bouncy');
const express = require('express');
const path = require('path');
const { create, engine } = require('express-handlebars');
bouncy(function(req, bounce) {
const host = req.headers.host;
console.log(`host=${host}`);
console.log(`req.url = ${req.url}`);
if (host === 'planetshah.com' || host === 'www.planetshah.com') {
if (req.url.includes('/mixes') || req.url.includes('.mixes.')) {
console.log('bouncing to 8002');
bounce(8002);
} else if (req.url.includes('/pwv')) {
console.log('bouncing to 8004');
bounce(8004);
} else bounce(8000);
}
if (host === 'assertivesolutions.ca' || host === 'www.assertivesolutions.ca') {
console.log('bouncing to 8001');
bounce(8001);
}
if (host === 'fmshahdesign.com' || host === 'www.fmshahdesign.com') {
console.log('bouncing to 8003');
bounce(8003);
}
}).listen(80);
...
/******** PWV ********/
const pwvApp = express();
pwvApp
.use(express.static(path.join(__dirname, 'planetshah.com\\pwv')))
.listen(8004);
pwvApp.get('/*', function(req, res) {
console.log(`pwvApp.get(/*): req.url = ${req.url}`);
const url = req.url.trim();
let file = 'index.html';
if (url === '/pwvlogic.js') {
file = 'pwvlogic.js';
console.log('pwvApp.get(/*): sending pwvlogic.js');
} else if (url.startsWith('/pwv/')) {
const parts = url.split('/');
parts.splice(0, 2);
file = parts.join('/');
console.log(`pwvApp.get(/*): sending ${file}`);
} else if (url === '/favicon.ico') {
file = 'favicon.ico';
}
res.sendFile(path.join(__dirname, `planetshah.com\\pwv\\${file}`), function(err) {
if (err) {
res.status(500).send(err);
}
});
});
console.log('pwvApp listening on port 8004');
/******** Music Mixes ********/
const musicMixApp = express();
musicMixApp
.use(express.static(path.join(__dirname, 'planetshah.com\\mixes')))
.listen(8002);
musicMixApp.get('/*', function(req, res) {
console.log(`musicMixApp.get(/*): req.url = ${req.url}`);
const url = req.url.trim();
let file = 'index.html';
if (
url.endsWith('.mixes.js')
|| url.includes('.html')
|| url.endsWith('.mp3')
|| url.endsWith('.css')
) {
file = url.substring(7);
file = file.split('?')[0];
file = decodeURIComponent(file);
console.log(`file = ${file}`);
}
res.sendFile(path.join(__dirname, `planetshah.com\\mixes\\${file}`), function(err) {
if (err) {
res.status(500).send(err);
}
});
});
console.log('musicMixApp listening on port 8002');
所以发生的情况是 pwvApp 在端口 8004 上运行,musicMixApp 在端口 8002 上运行。所有 http 请求都发送到端口 80,在该端口 bouncy 接收它并根据
req.headers.host
和 req.url
将其重新路由到不同的端口。当主机是“planetshah.com”时,它会检查 url 是否包含“pwv”或“mixes”,并将其分别路由到端口 8004 或 8002。
我在每个网站的每个 html 页面的
<head>
部分也有这个:
<link href="./styles.css" rel="stylesheet"/>
<link href="./favicon.ico" rel="icon"/>
每个网站的 styles.css 和 favicon.ico 文件位于不同的文件夹中,与引用它们的 html 文件处于同一级别。因此,它们对于每个站点都是完全分开的,并且获取它们应该不是问题......除非浏览器假设(错误地)我想要来自一个站点的文件,而实际上我想要来自另一个站点的文件。有什么办法可以阻止这种情况吗?绕过它?谢谢!
(如果我理解正确的话)
如果您将浏览器指向:
https://somedomain/foo
并且您有一个
<link>
标签,如下所示:
<link href="./favicon.ico" rel="icon"/>
这将解决:
https://somedomain/favicon.ico
而不是:
https://somedomain/foo/favicon.ico
如果您希望相对 URL 起作用,您有几种不同的选择,但最简单的可能是使用
<base>
HTML 标签:
<base href="/foo/" />
请注意,您需要最后的
/
。这允许像 ./favicon.ico
这样的相对 URL 被解析到 foo“目录”内部。