将所有根域请求重定向到 www.子域,保持 URL 完整

redirect all root domain request to www. subdomain, keeping the URL intact

我想将所有流量重定向到根域到 www. version 同时仍然保持 path/query 字符串完整,我该怎么做?我已经设置了一个 HAproxy 配置,如下所示:

frontend http
        bind *:80
        bind *:443

        acl has_www hdr_beg(host) -i www
        http-request redirect code 301 location http://www.%[hdr(host)]%[req.uri] unless has_www

但是这个会执行以下操作:example.com/abc?page=1 => www.example.com,我实际上不希望它执行以下操作:example.com/abc?page=1 => www.example.com/abc?page=1 - 什么我不见了?

如果您使用的是 HAProxy 1.5 及更高版本,这应该适合您

单域:

acl has_www hdr_beg(host) -i www
redirect prefix http://www.example.com code 301 unless has_www

多个域:(脏但有效)

# match non www requests:
acl has_www      hdr_beg(host) -i www.

# add a header that says we need to redirect these type of requests (will explain later)
http-request add-header X-Host-Redirect yes unless has_www

# rule to identify newly added headers
acl www_redirect hdr_cnt(X-Host-Redirect) eq 1

# where the magic happens (insert www. in front of all marked requests)
reqirep ^Host:\ (.*)$ Host:\ www. if www_redirect

# now hostname contains 'www.' so we can redirect to the same url
  redirect scheme http if www_redirect

我们添加新 header 的原因是因为似乎在 HAProxy 1.5 及更高版本中,ACLS 正在对每个引用进行评估。所以当你尝试在没有新 header 的情况下这样做时,它会这样做:

#catch all domains that begin with 'www.'
acl has_www      hdr_beg(host) -i www.
#insert www. in front of all non www requests
reqirep ^Host:\ (.*)$ Host:\ www. unless has_www
#now hostname contains 'www.' so when the next rule gets interpreted it does not match then fails  
#redirect to new url
redirect code 301 prefix / if has_www

希望这对您有所帮助。我已经在 HAProxy 1.5 上用 5 个不同的域对此进行了测试,它工作正常并且在重定向

时保持查询字符串完好无损

HAProxy 1.6 的 multi-domain 解决方案,重定向保留路径和查询参数:

frontend 443
  http-request redirect prefix https://www.%[hdr(host)] code 301 unless { hdr_beg(host) -i www. }