Redirecting www to non-www while maintaining the protocol HTTP or HTTPS

前端 未结 3 454
走了就别回头了
走了就别回头了 2021-01-15 05:56

I\'m attempting to redirect www to non-www for both HTTP and HTTPS requests. My root .htaccess looks like this:

RewriteEngine on

RewriteCond %{HTTP_HOST} ^w         


        
3条回答
  •  别那么骄傲
    2021-01-15 06:42

    Inspired by @MikeRockétt's answer, this is a "simplified" version, using just one condition (instead of three). This also canonicalises a FQDN (ie. by removing an optional trailing dot on the hostname):

    RewriteEngine On
    
    RewriteCond %{HTTP_HOST}#%{HTTPS}s ^www\.(.+?)\.?#(?:on(s)|)
    RewriteRule ^ http%2://%1%{REQUEST_URI} [R=301,L]
    

    This 301 redirects www to non-www while maintaining the same protocol, HTTP or HTTPS. Can be used unaltered in either .htaccess (directory context) or in the main server config / vhost. (Although, if you are in a virtualhost context you should probably be using a simpler mod_alias Redirect instead.)

    Explanation:

    • The TestString %{HTTP_HOST}#%{HTTPS}s (which evaluates to a string of the form "www.example.com#ons") is compared against the CondPattern ^www\.(.+?)\.?#(?:on(s)|)

      • The condition is successful for any request whose Host header starts "www.".

      • ^www\.(.+?)\.? first checks that the Host starts with "www." (if not, it fails early) and captures the remaining host header (excluding an optional trailing dot) in the %1 backreference. The regex that captures the domain name, ie. (.+?) is made non-greedy so that it does not capture the optional dot at the end.

      • # is just an arbitrary character that is used to separate the two values HTTP_HOST and HTTPS. Importantly, # cannot itself appear in either of these two values.
      • (?:on(s)|) is a non-capturing group that uses alternation to match against %{HTTPS}s. It either matches on(s) and captures the "s" (in the %2 backreference) or it matches anything and captures nothing (so %2 is empty).
    • Providing the previous condition is successful then the substitution string (http%2://%1%{REQUEST_URI}) is evaluated and the request redirected. The backreference %2, from the preceding CondPattern, either holds an "s" (to make "https" in the substitution) or is empty (ie. "http") and %1 is the hostname less the "www." prefix.

    • The REQUEST_URI server variable holds the full URL-path, including the slash prefix.

    must my server have an SSL certificate?

    Yes, otherwise the browser will block the connection (complaining about an invalid security certificate) - or simply time-out (because your server is not responding on port 443) and the request will not even reach your server.

提交回复
热议问题