Je vois le Nginx documentation HttpRewriteModule a un exemple pour réécrire un domaine préfixé www vers un domaine non préfixé www:
if ($Host ~* www\.(.*)) {
set $Host_without_www $1;
rewrite ^(.*)$ http://$Host_without_www$1 permanent; # $1 contains '/foo', not 'www.mydomain.com/foo'
}
Comment puis-je faire l'inverse - réécrire un domaine non préfixé par www dans un domaine préfixé par www? J'ai pensé que je pourrais peut-être faire quelque chose comme ceci, mais Nginx n'aime pas l'instruction if imbriquée.
if ($Host !~* ^www\.) { # check if Host doesn't start with www.
if ($Host ~* ([a-z0-9]+\.[a-z0-9]+)) { # check Host is of the form xxx.xxx (i.e. no subdomain)
set $Host_with_www www.$1;
rewrite ^(.*)$ http://$Host_with_www$1 permanent;
}
}
Je voulais également que cela fonctionne pour n'importe quel nom de domaine sans dire explicitement à Nginx de réécrire domain1.com -> www.domain1.com, domain2.com -> www.domain2.com, etc. car j'ai un grand nombre de domaines à réécrire .
Eh bien, je suppose que je n'ai pas vraiment besoin de la déclaration externe "si" car je ne vérifie que les domaines de la forme xxx.xxx de toute façon. Ce qui suit fonctionne pour moi, bien qu'il ne soit pas robuste. Faites-moi savoir s'il existe une meilleure solution.
if ($Host ~* ^([a-z0-9\-]+\.(com|net|org))$) {
set $Host_with_www www.$1;
rewrite ^(.*)$ http://$Host_with_www$1 permanent;
}
Edit: ajout d'un trait d'union à l'expression régulière car il s'agit d'un caractère valide dans un nom d'hôte.
Comme indiqué dans la documentation Nginx, vous devez éviter d'utiliser la directive if
dans Nginx si possible , car dès que vous avez un if
dans votre configuration, votre serveur a besoin pour évaluer chaque demande afin de décider si elle doit correspondre à cette if
ou non.
Une meilleure solution serait de multiples directives de serveur.
server {
listen 80;
server_name website.com;
return 301 $scheme://www.website.com$request_uri;
}
server {
listen 80;
server_name www.website.com;
...
}
Si vous essayez de servir un site compatible SSL (HTTPS), vous avez plus ou moins trois options différentes.
if
redoutée.if ($Host !~* ^www\.) {
rewrite ^(.*)$ http://www.$Host$1 permanent;
}
if ($Host ~* ^[^.]+\.[^.]+$) {
rewrite ^(.*)$ http://www.$Host$1 permanent;
}
Il est uniquement possible d'obtenir des noms d'hôtes valides car la demande ne parviendra jamais à votre serveur autrement, il n'est donc pas nécessaire de créer votre propre logique de validation.
La documentation de nginx met en garde contre l'utilisation de if pour la réécriture. Veuillez consulter le lien ici: http://wiki.nginx.org/Pitfalls#Server_Name
HTTP et HTTPS sans conditions if:
server {
listen 80;
listen 443;
server_name website.com;
return 301 $scheme://www.website.com$request_uri;
}
server {
listen 80;
listen 443 default_server ssl;
server_name www.website.com;
# Your config goes here #
}
Solution pour plusieurs domaines, travaillant sur nginx 1.17 pour moi:
server {
listen 80;
server_name .example.com;
set $Host_with_www $Host;
if ($Host !~* www\.(.*)) {
set $Host_with_www www.$Host;
}
return 301 https://$Host_with_www$request_uri;
}
Dans cet exemple de configuration, réécrit également HTTP sur HTTPS, si vous ne voulez pas réécrire - remplacez https: // par http: // dans la chaîne return
.
Si vous souhaitez conserver le protocole, utilisez $scheme
variable.