【发布时间】:2011-08-10 15:08:14
【问题描述】:
是否有机会以某种方式将 www 重定向到 node.js 中的非 www URL?由于节点 Web 服务器中没有 htaccess,我很好奇如何做到这一点。
【问题讨论】:
是否有机会以某种方式将 www 重定向到 node.js 中的非 www URL?由于节点 Web 服务器中没有 htaccess,我很好奇如何做到这一点。
【问题讨论】:
尽管这个问题已经有将近 3 年的历史了,但之前发布的答案(和他们的 cmets)存在一些微妙的问题,以及 cmets 中的一些很好的建议,但它们本身并没有回到答案中.以下是一些需要注意的重要事项:
http:// 或 https://;在开发环境和生产环境之间切换时,这会让生活变得很糟糕 - 请改用 req.protocol。req.protocol,您需要确保启用了 trust proxy 设置。这将确保 req.protocol 返回浏览器看到的协议,而不是最终到达您的应用服务器的协议。/^www/ 匹配,但使用/^www./ 格式化重定向URI。实际上,这可能不会咬人,但它会导致wwwgotcha.example.com之类的无限重定向循环。req.headers.host 而不是req.host,因为后者会去掉端口号。因此,如果您要处理对 www.example.com:3000 的请求,您需要将用户重定向到 www.example.com,减去正确的端口号。req.originalUrl 通常更安全,以防万一您碰巧在已挂载的“子应用程序”中运行。综上所述,这是我推荐的方法,考虑到上述情况:
function wwwRedirect(req, res, next) {
if (req.headers.host.slice(0, 4) === 'www.') {
var newHost = req.headers.host.slice(4);
return res.redirect(301, req.protocol + '://' + newHost + req.originalUrl);
}
next();
};
app.set('trust proxy', true);
app.use(wwwRedirect);
【讨论】:
您使用的是快递,对吗?如果是这样,您可以创建一个所有 GET 请求都通过的路由处理程序,检查它们是否指向“www”URL,并在适当时重定向到适当的非 www URL。
app.get('/*', function(req, res, next) {
if (req.headers.host.match(/^www/) !== null ) {
res.redirect('http://' + req.headers.host.replace(/^www\./, '') + req.url);
} else {
next();
}
})
【讨论】:
get 替换为all ;)
req.headers 是否存在! ;)
jmar777的回答的更新版本:
使用快递
server.use((req, res, next) => {
if (req.headers.host.startsWith('www.')) {
const newHost = req.headers.host.slice(4)
return res.redirect(
301,
`${req.protocol}://${newHost}${req.originalUrl}`,
)
}
next()
})
【讨论】:
这是一个基本示例,说明如何在 nodejs 中模仿 apache 的重定向指令的行为。
函数重定向接受正则表达式或字符串。
var http, redirect;
http = require("http");
redirect = function(host, res, pattern, redirect){
if (host == pattern || (pattern instanceof RegExp && host.match(pattern))) {
console.log("Redirected " + host);
res.writeHead(302, {
'location': redirect
});
res.end();
}};
http.createServer(function(req, res){
redirect(req.headers.host, res, /^www/, 'http://plouf.url');
redirect(req.headers.host, res, 'www.plouf.url', 'http://plouf.url');
res.writeHead(200, {
'Content-Type': 'text/plain'
});
res.end('Hello World\n');
}).listen(8000, '127.0.0.1');
【讨论】:
在 DevOps 和越来越多地采用托管平台的世界中,这类事情永远不应该由代码来处理。您应该改用基础设施来处理重定向。将此代码放入应用程序意味着如果顶点条目中出现问题,运营团队将无法缓解问题。此外,虽然它花哨、闪亮和时髦,但使用顶点作为您的站点 url 会限制操作在出现问题时重定向站点的能力,并在您想要进行蓝/绿、A/B 测试或地理重定向(在某些情况下)。您的代码和应用程序应该与 url 无关。
【讨论】:
如果您使用的是 Express,我同意上述 Sebastian 的观点,但需要稍作调整。我只是将它作为一个中间件,它将在所有请求上进行处理。
function removeWWW(req, res, next){
if (req.headers.host.match(/^www/) !== null ) {
res.redirect('http://' + req.headers.host.replace(/^www\./, '') + req.url);
} else {
next();
}
}
app.use(removeWWW);
【讨论】: