579 Stimmen

Nginx no-www zu www und www zu no-www

Ich verwende nginx in der Rackspace-Cloud nach einer Anleitung Ich habe das Netz durchsucht und kann das Problem bisher nicht lösen.

Ich möchte www.mysite.example zu gehen, um mysite.example als normal in .htaccess aus SEO- und anderen Gründen.

Meine /etc/nginx/sites-available/www.example.com.vhost Konfiguration:

server {
       listen 80;
       server_name www.example.com example.com;
       root /var/www/www.example.com/web;

       if ($http_host != "www.example.com") {
                 rewrite ^ http://example.com$request_uri permanent;
       }

Ich habe auch versucht

server {
       listen 80;
       server_name example.com;
       root /var/www/www.example.com/web;

       if ($http_host != "www.example.com") {
                 rewrite ^ http://example.com$request_uri permanent;
       }

Ich habe es auch versucht. Die beiden zweiten Versuche geben Redirect Loop-Fehler.

if ($host = 'www.example.com' ) {
rewrite ^ http://example.com$uri permanent;
}

Mein DNS ist standardmäßig eingerichtet:

site.example 192.192.6.8 A type at 300 seconds
www.site.example 192.192.6.8 A type at 300 seconds

(Beispiel-IPs und -Ordner wurden als Beispiele und als Hilfe für künftige Benutzer verwendet). Ich verwende Ubuntu 11.

855voto

TheBlackBenzKid Punkte 25272

HTTP-Lösung

Von der Dokumentation "Der richtige Weg ist, einen separaten Server zu definieren für example.org ":

server {
    listen       80;
    server_name  example.com;
    return       301 http://www.example.com$request_uri;
}

server {
    listen       80;
    server_name  www.example.com;
    ...
}

HTTPS-Lösung

Für diejenigen, die eine Lösung wünschen, die https:// ...

server {
        listen 80;
        server_name www.domain.example;
        # $scheme will get the http protocol
        # and 301 is best practice for tablet, phone, desktop and seo
        return 301 $scheme://domain.example$request_uri;
}

server {
        listen 80;
        server_name domain.example;
        # here goes the rest of your config file
        # example
        location / {

            rewrite ^/cp/login?$ /cp/login.php last;
            # etc etc...

        }
}

Anmerkung: Ursprünglich habe ich nicht berücksichtigt https:// in meiner Lösung, da wir Loadbalancer verwenden und unser Server https:// ein SSL-Zahlungsserver mit hohem Verkehrsaufkommen ist: wir mischen nicht https:// und http://.


Um die Nginx-Version zu überprüfen, verwenden Sie nginx -v .

Entfernen von www aus der URL mit Nginx-Umleitung

server {
    server_name  www.domain.example;
    rewrite ^(.*) http://domain.example$1 permanent;
}

server {
    server_name  domain.example;
    #The rest of your configuration goes here#
}

Sie benötigen also ZWEI Servercodes.

Hinzufügen des www zur URL mit Nginx-Redirect

Wenn Sie das Gegenteil brauchen, nämlich eine Umleitung von domain.example zu www.domain.example können Sie dies verwenden:

server {
    server_name  domain.example;
    rewrite ^(.*) http://www.domain.example$1 permanent;
}

server {
    server_name  www.domain.example;
    #The rest of your configuration goes here#
}

Wie Sie sich vorstellen können, ist dies genau das Gegenteil und funktioniert auf die gleiche Weise wie das erste Beispiel. Auf diese Weise erhalten Sie keine SEO-Bewertungen, da es sich um eine vollständige Perm-Redirect und Verschiebung handelt. Es wird kein WWW erzwungen und das Verzeichnis angezeigt!

Ein Teil meines Codes ist unten zur besseren Übersicht dargestellt:

server {
    server_name  www.google.com;
    rewrite ^(.*) http://google.com$1 permanent;
}
server {
       listen 80;
       server_name google.com;
       index index.php index.html;
       ####
       # now pull the site from one directory #
       root /var/www/www.google.com/web;
       # done #
       location = /favicon.ico {
                log_not_found off;
                access_log off;
       }
}

440voto

Fleshgrinder Punkte 15023

Eigentlich brauchen Sie nicht einmal eine Neufassung.

server {
    #listen 80 is default
    server_name www.example.com;
    return 301 $scheme://example.com$request_uri;
}

server {
    #listen 80 is default
    server_name example.com;
    ## here goes the rest of your conf...
}

Da meine Antwort mehr und mehr Stimmen erhält, aber auch die oben genannten. Sie sollten niemals eine rewrite in diesem Zusammenhang. Warum? Weil nginx eine Suche verarbeiten und starten muss. Wenn Sie return (die in jeder Nginx-Version verfügbar sein sollte), wird die Ausführung direkt gestoppt. Dies ist in jedem Kontext vorzuziehen.

Leiten Sie sowohl Nicht-SSL- als auch SSL-Seiten auf ihre Nicht-WWW-Gegenstücke um:

server {
    listen               80;
    listen               443 ssl;
    server_name          www.example.com;
    ssl_certificate      path/to/cert;
    ssl_certificate_key  path/to/key;

    return 301 $scheme://example.com$request_uri;
}

server {
    listen               80;
    listen               443 ssl;
    server_name          example.com;
    ssl_certificate      path/to/cert;
    ssl_certificate_key  path/to/key;

    # rest goes here...
}

があります。 $scheme Variable enthält nur http wenn Ihr Server nur auf Port 80 lauscht (Standard) und die Option listen nicht das ssl Stichwort. Wenn Sie die Variable nicht verwenden, bringt Ihnen das keinen Leistungsgewinn.

Beachten Sie, dass Sie noch mehr Serverblöcke benötigen, wenn Sie HSTS verwenden, da die HSTS-Header nicht über unverschlüsselte Verbindungen gesendet werden sollten. Sie benötigen also unverschlüsselte Serverblöcke mit Umleitungen und verschlüsselte Serverblöcke mit Umleitungen und HSTS-Headern.

Leiten Sie alles auf SSL um (persönliche Konfiguration auf UNIX mit IPv4, IPv6, SPDY, ...):

#
# Redirect all www to non-www
#
server {
    server_name          www.example.com;
    ssl_certificate      ssl/example.com/crt;
    ssl_certificate_key  ssl/example.com/key;
    listen               *:80;
    listen               *:443 ssl spdy;
    listen               [::]:80 ipv6only=on;
    listen               [::]:443 ssl spdy ipv6only=on;

    return 301 https://example.com$request_uri;
}

#
# Redirect all non-encrypted to encrypted
#
server {
    server_name          example.com;
    listen               *:80;
    listen               [::]:80;

    return 301 https://example.com$request_uri;
}

#
# There we go!
#
server {
    server_name          example.com;
    ssl_certificate      ssl/example.com/crt;
    ssl_certificate_key  ssl/example.com/key;
    listen               *:443 ssl spdy;
    listen               [::]:443 ssl spdy;

    # rest goes here...
}

Ich denke, Sie können sich jetzt selbst andere Verbindungen mit diesem Muster vorstellen.

Mehr von meinen Konfigs? Unter hier et hier .

75voto

cnst Punkte 23716
  1. Bewährte Praxis: getrennt server mit fest kodiertem server_name

Die beste Praxis bei nginx ist die Verwendung eines separaten server für eine Weiterleitung wie diese (nicht gemeinsam mit dem server Ihrer Hauptkonfiguration), alles hart zu kodieren und überhaupt keine regulären Ausdrücke zu verwenden.

Bei der Verwendung von HTTPS kann es auch notwendig sein, die Domänen hart zu kodieren, da Sie im Voraus wissen müssen, welche Zertifikate Sie bereitstellen werden.

server {
    server_name www.example.com;
    return  301 $scheme://example.com$request_uri;
}
server {
    server_name www.example.org;
    return  301 $scheme://example.org$request_uri;
}
server {
    server_name example.com example.org;
    # real configuration goes here
}

  1. Verwendung regulärer Ausdrücke in server_name

Wenn Sie eine Reihe von Websites haben und sich nicht um die ultimative Leistung kümmern, sondern wollen, dass jede einzelne von ihnen die gleichen Richtlinien in Bezug auf die www. Präfix, dann können Sie reguläre Ausdrücke verwenden. Die beste Praxis ist die Verwendung eines separaten server würde immer noch gelten.

Beachten Sie, dass diese Lösung schwierig wird, wenn Sie https verwenden, da Sie dann ein einziges Zertifikat für alle Ihre Domänennamen haben müssen, wenn dies richtig funktionieren soll.


nicht www zu www mit Regex in einem eigenen Single server für alle Standorte:

server {
    server_name ~^(?!www\.)(?<domain>.+)$;
    return  301 $scheme://www.$domain$request_uri;
}

www an Nicht www mit Regex in einem speziellen Einzel server für alle Standorte:

server {
    server_name ~^www\.(?<domain>.+)$;
    return  301 $scheme://$domain$request_uri;
}

www an Nicht www mit Regex in einem eigenen server nur für einige Standorte:

Es kann notwendig sein, die Regex auf einige Domänen zu beschränken, dann können Sie etwas wie dieses verwenden, um nur mit www.example.org , www.example.com et www.subdomain.example.net :

server {
    server_name ~^www\.(?<domain>(?:example\.org|example\.com|subdomain\.example\.net))$;
    return  301 $scheme://$domain$request_uri;
}

Testen regulärer Ausdrücke mit nginx

Sie können testen, ob die Regex wie erwartet funktioniert, indem Sie pcretest auf Ihrem System, was genau dasselbe ist wie pcre Bibliothek, die Ihr Nginx für reguläre Ausdrücke verwenden wird:

% pcretest 
PCRE version 8.35 2014-04-04

  re> #^www\.(?<domain>(?:example\.org|example\.com|subdomain\.example\.net))$#
data> test
No match
data> www.example.org
 0: www.example.org
 1: example.org
data> www.test.example.org
No match
data> www.example.com
 0: www.example.com
 1: example.com
data> www.subdomain.example.net
 0: www.subdomain.example.net
 1: subdomain.example.net
data> subdomain.example.net
No match
data> www.subdomain.example.net.
No match
data> 

Beachten Sie, dass Sie sich keine Gedanken über nachgestellte Punkte oder Groß- und Kleinschreibung machen müssen, da nginx sich bereits darum kümmert, wie in nginx-Server-Namen-Regex, wenn "Host"-Header einen Punkt am Ende hat .


  1. Streuung if innerhalb bestehender server / HTTPS:

Diese endgültige Lösung wird im Allgemeinen nicht als die beste Praxis angesehen, aber sie funktioniert trotzdem und erfüllt ihre Aufgabe.

Wenn Sie HTTPS verwenden, kann diese endgültige Lösung sogar einfacher zu warten sein, da Sie nicht eine ganze Reihe von ssl-Direktiven zwischen den verschiedenen server Definitionen, und könnten stattdessen die Snippets nur auf den benötigten Servern platzieren, was die Fehlersuche und Wartung Ihrer Websites erleichtert.


nicht www zu www :

if ($host ~ ^(?!www\.)(?<domain>.+)$) {
    return  301 $scheme://www.$domain$request_uri;
}

www an Nicht www :

if ($host ~ ^www\.(?<domain>.+)$) {
    return  301 $scheme://$domain$request_uri;
}

Festcodierung einer einzigen bevorzugten Domäne

Wenn Sie etwas mehr Leistung und Konsistenz zwischen mehreren Domänen wünschen, können Sie eine einzelne server verwenden können, kann es dennoch sinnvoll sein, eine einzige bevorzugte Domäne explizit zu kodieren:

if ($host != "example.com") {
    return  301 $scheme://example.com$request_uri;
}

Referenzen:

46voto

Martin Höger Punkte 784

Möglicherweise möchten Sie die gleiche Konfiguration für mehrere Domänen verwenden.

Das folgende Snippet entfernt das www vor jeder Domain:

if ($host ~* ^www\.(.*)$) {
    rewrite / $scheme://$1 permanent;
}

31voto

Red Punkte 3348

Sie benötigen zwei Serverblöcke.

Fügen Sie diese in Ihre Konfigurationsdatei ein, z. B. /etc/nginx/sites-available/sitename

Nehmen wir an, Sie entscheiden sich für http://example.com als die zu verwendende Hauptadresse.

Ihre Konfigurationsdatei sollte wie folgt aussehen:

server {
        listen 80;
        listen [::]:80;
        server_name www.example.com;
        return 301 $scheme://example.com$request_uri;
}
server {
        listen 80;
        listen [::]:80;
        server_name example.com;

        # this is the main server block
        # insert ALL other config or settings in this server block
}

Der erste Serverblock enthält die Anweisungen zur Umleitung aller Anfragen mit dem Präfix "www". Er hört auf Anfragen für die URL mit dem Präfix "www" und leitet sie weiter.

Sie tut nichts anderes.

Der zweite Serverblock enthält Ihre Hauptadresse - die URL, die Sie verwenden möchten. Alle anderen Einstellungen gehören hierher, wie root , index , location , usw. Überprüfen Sie die Standarddatei auf diese anderen Einstellungen, die Sie in den Serverblock aufnehmen können.

Der Server benötigt zwei DNS-A-Einträge.

Name: @ IPAddress: your-ip-address (for the example.com URL)

Name: www IPAddress: your-ip-address (for the www.example.com URL)

Für ipv6 erstellen Sie ein Paar AAAA-Datensätze unter Verwendung Ihrer-ipv6-Adresse.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X