我正在尝试让 nginx 通过添加或删除 www. 前缀来重定向从任何域收到的每个请求。
这是用于小型重定向服务。如果您将 www.any.domain 指向它,它会将 www.any.domain/* 重定向到 any.domain/*。如果您将 any.domain 指向它,它会将 any.domain/* 重定向到 www.any.domain/*。
实际上,这不会导致重定向循环,因为两个域(any.domain 或 www.any.domain)中只有一个会指向此服务。另一个指向另一台服务器上的网站。
这应该适用于任何域。成千上万个不同的域,因此必须具有正则表达式通配符匹配。互联网上的任何东西都可以指向它,这不是 nginx 关心的问题,因为这将在它上面/之前的一层处理。每个带有 HTTP_HOST 标头的请求要么有 www,要么没有,在这两种情况下都应该重定向,因此服务器应该重定向它收到的所有请求。
域名不以 www. 开头的情况很容易,但我无法弄清楚如何捕捉域名以 www. 开头的情况,然后仅使用域名的其余部分。
我尝试搜索,但 a) 几乎没有人同时重定向两个方向,b) 大多数人只关心一个域名,因此他们对其进行硬编码,c) 一旦你越过这个域名,人们就会高呼“如果是邪恶的”。所以这没什么帮助。
这是我目前所拥有的:
http {
server {
listen 80 default_server;
server_name _;
# add www. to URLs that don't start with it.
if ($host !~* ^www\.) {
rewrite ^(.*)$ http://www.$host$1 permanent;
}
# but what about URLs that DO start with www.? How do I remove it?
}
}
这用于为您的网站设置 DNS。如果您希望您的网站在 mydomain.com 上提供服务,请将 mydomain.com 指向您的网站,将 www.mydomain.com 指向此重定向器。如果您希望您的网站在 www.mydomain.com 上提供服务,请将 www.mydomain.com 指向您的网站,将 mydomain.com 指向此重定向器。
答案1
使用两个服务器块
这实际上是在文档中:
命名的正则表达式捕获稍后可以用作变量:
server { server_name ~^(www\.)?(?<domain>.+)$; location / { root /sites/$domain; } }
应用于问题中的用例,所需的服务器块因此是:
server {
server_name ~^(www\.)(?<domain>.+)$;
return 301 $scheme://$domain$request_uri;
}
综合起来
这完全的该问题所需的服务器配置是:
server {
listen 80;
server_name ~^(www\.)(?<domain>.+)$;
return 301 $scheme://$domain$request_uri;
}
server {
listen 80 default_server;
return 301 $scheme://www.$host$request_uri;
}
这样配置就是非常简单,并且没有使用if
(一般来说应该避免)。
答案2
类似,并且没有测试过,但大致如下:
http {
server {
listen 80 default_server;
server_name _;
# redirect www.foo.com -> foo.com
if ($host ~* ^www\.) {
rewrite ^www\.(.*)$ http://$1 permanent;
}
}
}
答案3
看起来我找到了解决方案https://blog.engineyard.com/2011/useful-rewrites-for-nginx
http {
server {
listen 80 default_server;
server_name _;
if ($host !~* ^www\.) {
rewrite ^(.*)$ $scheme://www.$host$1 permanent;
break;
}
if ($host ~* ^www\.(.*)) {
set $host_without_www $1;
rewrite ^(.*)$ $scheme://$host_without_www$1 permanent;
break;
}
}
}