Node.js www - 非www重定向

Pon*_*ono 36 node.js express

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

jma*_*777 80

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

  1. 不要硬编码http://https://在重定向URI; 这使得在dev和prod环境之间切换时生活很糟糕 - req.protocol而是使用.
  2. 另请注意,为了在req.protocol执行SSL终止的代理(例如Elastic Load Balancer)后面可靠地使用,您需要确保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指出的那样,当你从用于搜索引擎优化目的的www到非www(反之亦然),你通常会想要使用301重定向.
  6. 最后一个问题是最小的问题,但req.originalUrl在创建重定向URI时通常更安全,以防万一你恰好在已安装的"子应用程序"中运行.

所有这一切,这是我推荐的方法,考虑到上述因素:

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);
Run Code Online (Sandbox Code Playgroud)

  • @JamesSpence好问题.你不会(不能)在DNS级别执行HTTP(S)和/或www重定向,但是nginx肯定是适合这项工作的工具.当涉及到各种各样的攻击缓解时,Nginx也是一个有价值的工具,所以我坦白地说,没有它就离开家,可以这么说.话虽如此,在node-land中执行此操作也没有任何根本性的错误,特别是如果您不想在混合中引入新的反向代理,否则将无用. (2认同)

S M*_*S M 28

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

  • 你可以用`all`替换`get`;) (7认同)
  • 您可以使用req.host:http://expressjs.com/api.html#req.host我也建议使用req.protocol +'://'而不是硬编码http:// (5认同)
  • 并检查之前是否存在`req.headers`!;) (2认同)
  • 另外,请确保将301设置为重定向的第一个参数(默认情况下,Express重定向为302) (2认同)
  • 好的,最后一条评论-我试图在一个新的答案中总结各种陷阱(抱歉,该评论为垃圾邮件!):http://stackoverflow.com/a/23816083/376789 (2认同)

小智 8

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()
})
Run Code Online (Sandbox Code Playgroud)