繁体   English   中英

Node.js www - 非 www 重定向

[英]Node.js www - non www redirection

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

尽管这个问题已有近 3 年的历史,但之前发布的答案(及其评论)存在一些微妙的问题,以及评论中的一些好的建议并没有回到答案本身。 这里有一些重要的事情需要注意:

  1. 不要在重定向 URI 中硬编码http://https:// 在开发环境和产品环境之间切换时,这会让生活变得很糟糕 - 请改用req.protocol
  2. 另请注意,为了在执行 SSL 终止的代理(例如 Elastic Load Balancer)之后可靠地使用req.protocol ,您需要确保启用了trust proxy设置。 这将确保req.protocol返回浏览器看到的协议,而不是最终到达您的应用服务器的协议。
  3. 接受的答案有一个逻辑错误,因为它匹配/^www/ ,但使用/^www./格式化重定向 URI。 在实践中,这可能不会咬任何人,但它导致像wwwgotcha.example.com这样的无限重定向循环。
  4. 请务必使用req.headers.host而不是req.host ,因为后者会去掉端口号。 因此,如果您要处理对www.example.com:3000的请求,您需要将用户重定向到www.example.com ,减去正确的端口号。
  5. 正如Dário 所指出的,在从 www 转到非 www(反之亦然)时,您通常会希望使用 301 重定向来实现 SEO 目的。
  6. 最后一个问题是最次要的,但在创建重定向 URI 时使用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 请求 go 的路由处理程序,检查它们是否指向“www”URL,并在适当的情况下重定向到适当的非 www ZE6B391A8D2C4D45902A23A8。

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

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

function 重定向采用正则表达式或字符串。

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

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

在 DevOps 和越来越多地采用托管平台的世界中,这种事情永远不应该由代码来处理。 您应该改用基础设施来处理重定向。 将此代码放入应用程序意味着如果顶点条目中出现故障,运营团队将无法缓解问题。 此外,虽然它很漂亮,shiny 和臀部,使用顶点作为您的站点 url 限制了操作重定向站点的能力,如果 go 出现问题,或者当您想要测试蓝色/绿色时,A 会导致/B75A89A6BZ 出现问题地理重定向(在某些情况下)。 您的代码和应用程序应该与 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);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM