Node.js www - 非www重定向

时间:2011-08-10 15:08:14

标签: node.js express

有没有机会以某种方式将www重定向到node.js中的非www网址?由于节点Web服务器中没有htaccess,我很好奇如何做到这一点。

6 个答案:

答案 0 :(得分:71)

即使这个问题已经将近3年了,但是之前发布的答案(以及他们的评论)还有一些微妙的问题,以及评论中的一些好建议,这些建议没有回到答案本身。以下是一些需要注意的重要事项:

  1. 请勿对重定向URI中的http://https://进行硬编码;这会在dev和prod环境之间切换时生活变得很糟糕 - 请改用req.protocol
  2. 另请注意,为了在执行SSL终止的代理(例如Elastic Load Balancer)后面可靠地使用req.protocol,您需要确保已启用trust proxy设置。这将确保req.protocol返回浏览器看到的协议,而不是最终将其发送到您的应用服务器的协议。
  3. 接受的答案有一个逻辑错误,因为它与/^www/匹配,但是将重定向URI格式化为/^www./。在实践中,可能不会咬人,但导致无限重定向循环,例如wwwgotcha.example.com
  4. 请务必使用req.headers.host代替req.host,因为后者删除了端口号。因此,如果您要处理www.example.com:3000请求,则会将用户重定向到www.example.com,减去正确的端口号。
  5. 作为Dário pointed out,您通常希望在从www到非www(或反之亦然)进行搜索引擎优化时使用301重定向。
  6. 最后一个问题是最小问题,但在创建重定向URI时使用req.originalUrl通常会更安全,以防万一您恰好在已安装的“子应用”中运行。
  7. 所有这一切,这是我推荐的方法,考虑到上述因素:

    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);
    

答案 1 :(得分:27)

你正在使用快递,对吧?如果是这样,您可以创建一个所有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();     
  }
})

答案 2 :(得分:4)

这是一个基本的例子,说明如何在nodejs中模仿apache的重定向指令的行为。

函数redirect采用RegEx或字符串。

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');

答案 3 :(得分:1)

在DevOps的世界中以及托管平台越来越多的采用,这种类型的东西永远不应该被代码处理。您应该使用基础结构来处理重定向。将此代码放入应用程序意味着如果顶点条目中出现故障,操作团队无法减轻问题。此外,虽然它是花哨,闪亮和时尚,使用顶点作为您的网站网址限制操作重定向网站的能力,如果出现问题,并导致问题,当您想要进行蓝/绿,A / B测试或地理重定向(在某些情况下)。您的代码和应用程​​序应与url无关。

答案 4 :(得分:0)

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()
})

答案 5 :(得分:-1)

我同意Sebastian上面的一个小调整,如果你使用Express。我只是将它作为中间件,它将在所有请求中处理。

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);