Lösung für mehrere 302-Antworten im Nginx-Proxy (Nginx Follow 302)

Lösung für mehrere 302-Antworten im Nginx-Proxy (Nginx Follow 302)

Proxying mehrerer 302er mit proxy_intercept_errors und recursive_error_pages

302 ist ein häufig verwendeter Statuscode im HTTP-Protokoll. Es handelt sich um eine von mehreren Umleitungsmethoden und seine Semantik wird häufig als „Vorübergehend verschoben“ interpretiert. Übrigens wird 302 in der Realität häufig falsch verwendet (gemischt mit 303 und 307). In HTTP/1.1 lautet die Semantik „Gefunden“.

302 ist manchmal sehr offensichtlich und manchmal versteckter. Der einfachste Fall ist, wenn wir eine URL A in den Browser eingeben und die Adressleiste des Browsers automatisch zu B springt und dann eine Webseite öffnet. Diese Situation ist höchstwahrscheinlich 302.

Bei in Webseiten eingebetteten Playern treten häufig subtilere Situationen auf. Wenn Sie beispielsweise eine Youku-Videowiedergabeseite öffnen, finden Sie häufig den Schatten von 302, indem Sie das Paket erfassen und beobachten. Da diese URLs allerdings nicht direkt im Browser geöffnet werden, sind in der Adressleiste des Browsers auch keine Änderungen zu sehen. Wenn man sich diese URLs gezielt heraussucht und in die Adressleiste des Browsers kopiert, sind diese natürlich trotzdem zu sehen.

Youku wurde im vorherigen Absatz erwähnt. Tatsächlich verwenden die meisten Online-Video-Websites mittlerweile 302. Der Grund ist ganz einfach. Video-Websites haben im Allgemeinen viel Verkehr und verwenden CDN. Der einzige Unterschied besteht darin, ob Sie ein selbst erstelltes oder ein kommerzielles CDN verwenden. Und aufgrund der Umleitungssemantik von 302 (ich wiederhole, die Semantik von 302 wird häufig falsch verwendet. Wenn wir 302 verwenden, sollten wir wahrscheinlich 303 oder 307 verwenden, aber darauf werden wir später nicht näher eingehen) kann es gut mit der Planung im CDN kombiniert werden.

Schauen wir uns ein Beispiel an. Öffnen Sie eine NetEase-Videowiedergabeseite, holen Sie sich das Paket und suchen Sie die URL mit dem Status 302. Zum Beispiel:

http://flv.bn.netease.com/tvmrepo/2014/8/5/P/EA3I1J05P/SD/EA3I1J05P-mobile.mp4

Wenn wir es in die Adressleiste des Browsers kopieren, werden wir feststellen, dass die Adressleiste schnell zu einer anderen URL wechselt. Diese URL ist unsicher und könnte lauten:

http://14.18.140.83/f6c00af500000000-1408987545-236096587/data6/flv.bn.netease.com/tvmrepo/2014/8/5/P/EA3I1J05P/SD/EA3I1J05P-mobile.mp4

Die Verwendung des Curl-Tools veranschaulicht den gesamten Vorgang deutlicher:

curl -I "http://flv.bn.netease.com/tvmrepo/2014/8/5/P/EA3I1J05P/SD/EA3I1J05P-mobile.mp4" -L
HTTP/1.1 302 vorübergehend verschoben 
Server: nginx 
Datum: Montag, 25. August 2014, 14:49:43 GMT 
Inhaltstyp: text/html 
Inhaltslänge: 154 
Verbindung: Keep-Alive 
NG: CCN-SW-1-5L2 
X-Mod-Name: GSLB/3.1.0 
Standort: http://119.134.254.9/flv.bn.netease.com/tvmrepo/2014/8/5/P/EA3I1J05P/SD/EA3I1J05P-mobile.mp4 

HTTP/1.1 302 vorübergehend verschoben 
Server: nginx 
Datum: Montag, 25. August 2014, 14:49:41 GMT 
Inhaltstyp: text/html 
Inhaltslänge: 154 
Verbindung: Keep-Alive 
X-Mod-Name: Mvod-Server/4.3.3 
Standort: http://119.134.254.7/cc89fdac00000000-1408983581-2095617481/data4/flv.bn.netease.com/tvmrepo/2014/8/5/P/EA3I1J05P/SD/EA3I1J05P-mobile.mp4 
NG: CHN-SW-1-3Y1 

HTTP/1.1 200 OK 
Server: nginx 
Datum: Montag, 25. August 2014, 14:49:41 GMT 
Inhaltstyp: video/mp4 
Inhaltslänge: 3706468 
Letzte Änderung: Montag, 25. August 2014, 00:23:50 GMT 
Verbindung: Keep-Alive 
Cache-Steuerung: kein Cache 
ETag: "53fa8216-388e64" 
NG: CHN-SW-1-3g6 
X-Mod-Name: Mvod-Server/4.3.3 
Akzeptierte Bereiche: Bytes

Wie Sie sehen, traten dabei zwei 302-Fehler auf.

Lassen wir dieses Beispiel zunächst einmal beiseite und sprechen wir über einen anderen wichtigen Begriff: Proxy. Wir sagen oft scherzhaft, dass einige Leader vom Typ 302 und andere vom Typ Proxy sind. Ein Leiter vom Typ 302 gibt eine Aufgabe schnell an andere weiter, sobald sie durch seine Hände gegangen ist, während ein Leiter vom Typ Proxy an der Aufgabe teilnimmt und sie sogar vollständig abschließt.

Zurück zum obigen Beispiel: Wenn beim Zugriff auf eine URL mehrere 302-Ausfälle auftreten, was sollen wir tun, wenn wir einen Proxy mit Nginx entwerfen müssen, um alle diese 302-Ausfälle in der Mitte zu verbergen?

1. Ursprünglicher Proxy

Wir wissen, dass Nginx selbst ein ausgezeichneter Proxyserver ist. Lassen Sie uns daher zunächst einen Nginx-Forward-Proxy mit der Server-IP 192.168.109.128 (eine meiner virtuellen Testmaschinen) einrichten.

Die Erstkonfiguration gestaltet sich vereinfacht wie folgt:

Server {
    hören Sie 80;
    Standort / {
        umschreiben_von_lua '
            ngx.exec("/proxy-to" .. ngx.var.request_uri)
        ';
    }

    Standort ~ /proxy-to/([^/]+)(.*) {
        Proxy-Passwort http://$1$2$ist_Argumente$Abfragezeichenfolge;

    }
}

Die erreichte Funktion besteht darin, dass bei der Verwendung

http://192.168.109.128/xxxxxx

Wenn Sie auf den Proxy zugreifen, werden Sie zum realen Server weitergeleitet, der durch xxxxxx dargestellt wird.

Die Testergebnisse lauten wie folgt:

curl -I "http://192.168.109.128/flv.bn.netease.com/tvmrepo/2014/8/5/P/EA3I1J05P/SD/EA3I1J05P-mobile.mp4" -L
HTTP/1.1 302 vorübergehend verschoben 
Server: nginx/1.4.6 
Datum: Montag, 25. August 2014, 14:50:54 GMT 
Inhaltstyp: text/html 
Inhaltslänge: 154 
Verbindung: Keep-Alive 
NG: CCN-SW-1-5L2 
X-Mod-Name: GSLB/3.1.0 
Standort: http://183.61.140.24/flv.bn.netease.com/tvmrepo/2014/8/5/P/EA3I1J05P/SD/EA3I1J05P-mobile.mp4 

HTTP/1.1 302 vorübergehend verschoben 
Server: nginx 
Datum: Montag, 25. August 2014, 14:50:55 GMT 
Inhaltstyp: text/html 
Inhaltslänge: 154 
Verbindung: Keep-Alive 
X-Mod-Name: Mvod-Server/4.3.3 
Standort: http://183.61.140.20/540966e500000000-1408983655-236096587/data1/flv.bn.netease.com/tvmrepo/2014/8/5/P/EA3I1J05P/SD/EA3I1J05P-mobile.mp4 
NG: CHN-ZJ-4-3M4 

HTTP/1.1 200 OK 
Server: nginx 
Datum: Montag, 25. August 2014, 14:50:55 GMT 
Inhaltstyp: video/mp4 
Inhaltslänge: 3706468 
Letzte Änderung: Montag, 25. August 2014, 00:31:03 GMT 
Verbindung: Keep-Alive 
Cache-Steuerung: kein Cache 
ETag: "53fa83c7-388e64" 
NG: CHN-ZJ-4-3M4 
X-Mod-Name: Mvod-Server/4.3.3 
Akzeptierte Bereiche: Bytes

Man erkennt, dass zwar ein Proxy zum Einsatz kommt, der Vorgang sich jedoch nicht vom ursprünglichen Zugriff unterscheidet. Der Zugriff erfolgt wie folgt:

http://192.168.109.128/flv.bn.netease.com/tvmrepo/2014/8/5/P/EA3I1J05P/SD/EA3I1J05P-mobile.mp4

Wenn Nginx die Anfrage weiterleitet an

http://flv.bn.netease.com/tvmrepo/2014/8/5/P/EA3I1J05P/SD/EA3I1J05P-mobile.mp4

Letzterer gibt sofort eine 302 zurück, sodass Nginx als Proxy die 302 an den Client zurückgibt, der Client die Anforderung erneut initiiert und dann die vorherige 302 wiederholt. Dies veranschaulicht ein Problem. Sobald das Backend des Nginx-Proxys 302 zurückgibt, wird die Verbindung des Clients zum Nginx-Proxy getrennt und Nginx kann nicht die Rolle eines vollwertigen Proxys spielen.

2. Erste Überarbeitung

Ändern Sie die Konfigurationsdatei wie folgt:

Server {
    hören Sie 80;
    Standort / {
        umschreiben_von_lua '
            ngx.exec("/proxy-to" .. ngx.var.request_uri)
        ';
    }

    Standort ~ /proxy-to/([^/]+)(.*) {
        Proxy-Passwort http://$1$2$ist_Argumente$Abfragezeichenfolge;
        Fehlerseite 302 = @Fehlerseite_302;

    }
    Standort @error_page_302 {
        umschreiben_von_lua '
            lokales _, _, upstream_http_location = Zeichenfolge.find(ngx.var.upstream_http_location, "^http:/(.*)$")
            ngx.header["zzzz"] = "/proxy-to" .. upstream_http_location
            ngx.exec("/proxy-to" .. upstream_http_location);
        ';

    }
}

Der Unterschied zum Obigen besteht darin, dass eine Fehlerseite verwendet wird. Der Zweck besteht darin, dass, wenn festgestellt wird, dass das Proxy-Backend 302 zurückgibt, der Zielort dieser 302 weiterhin zum Proxy weitergeleitet wird, anstatt ihn direkt an den Client zurückzugeben. Und diese Logik beinhaltet die Bedeutung der Rekursion, indem sie 302 den ganzen Weg verfolgt, bis sie schließlich zur Adresse 200 zurückkehrt. Die Testergebnisse lauten wie folgt:

curl -I "http://192.168.109.128/flv.bn.netease.com/tvmrepo/2014/8/5/P/EA3I1J05P/SD/EA3I1J05P-mobile.mp4" -L
HTTP/1.1 302 vorübergehend verschoben 
Server: nginx/1.4.6 
Datum: Montag, 25. August 2014, 15:01:17 GMT 
Inhaltstyp: text/html 
Inhaltslänge: 154 
Verbindung: Keep-Alive 
NG: CCN-SW-1-5L2 
X-Mod-Name: GSLB/3.1.0 
Standort: http://183.61.140.24/flv.bn.netease.com/tvmrepo/2014/8/5/P/EA3I1J05P/SD/EA3I1J05P-mobile.mp4 

HTTP/1.1 302 vorübergehend verschoben 
Server: nginx 
Datum: Montag, 25. August 2014, 15:01:17 GMT 
Inhaltstyp: text/html 
Inhaltslänge: 154 
Verbindung: Keep-Alive 
X-Mod-Name: Mvod-Server/4.3.3 
Standort: http://183.61.140.20/a90a952900000000-1408984277-236096587/data1/flv.bn.netease.com/tvmrepo/2014/8/5/P/EA3I1J05P/SD/EA3I1J05P-mobile.mp4 
NG: CHN-ZJ-4-3M4 

HTTP/1.1 200 OK 
Server: nginx 
Datum: Montag, 25. August 2014, 15:01:17 GMT 
Inhaltstyp: video/mp4 
Inhaltslänge: 3706468 
Letzte Änderung: Montag, 25. August 2014, 00:31:03 GMT 
Verbindung: Keep-Alive 
Cache-Steuerung: kein Cache 
ETag: "53fa83c7-388e64" 
NG: CHN-ZJ-4-3M4 
X-Mod-Name: Mvod-Server/4.3.3 
Akzeptierte Bereiche: Bytes

Man sieht, dass diese Änderung noch immer erfolglos ist!

Warum? Nach der Analyse haben wir an der Position @error_page_302 eine Header-Druckanweisung hinzugefügt, im Test wird der Header jedoch nicht ausgedruckt, was zeigt, dass der Prozess die Position @error_page_302 nicht aufgerufen hat.

Der Grund ist

Fehlerseite 302 = @Fehlerseite_302;

Standardmäßig ist error_page der Rückgabecode dieses Prozesses. Als Proxy sollte bei dieser Verarbeitung der Statuscode 200 lauten, solange die Antwort des Upstream-Servers erfolgreich weitergeleitet wird. Das heißt, was wir wirklich überprüfen müssen, ist der vom Backend-Server des Proxys zurückgegebene Statuscode, nicht der vom Proxy selbst zurückgegebene Statuscode. Ein Blick auf das Nginx-Wiki zeigt, dass die Direktive proxy_intercept_errors genau dies bewirkt:

Syntax: proxy_intercept_errors on | off;
Standard:  
proxy_intercept_errors aus;
Kontext: http, Server, Standort
Bestimmt, ob geproxiete Antworten mit Codes größer oder gleich 300 an einen Client übergeben oder zur Verarbeitung mit der Direktive error_page an nginx umgeleitet werden sollen.

3. Zweite Revision

Server {
    hören Sie 80;
    proxy_intercept_errors ein;
    Standort / {
        umschreiben_von_lua '
            ngx.exec("/proxy-to" .. ngx.var.request_uri)
        ';
    }
    Standort ~ /proxy-to/([^/]+)(.*) {
        Proxy-Passwort http://$1$2$ist_Argumente$Abfragezeichenfolge;
        Fehlerseite 302 = @Fehlerseite_302;

    }
    Standort @error_page_302 {
        umschreiben_von_lua '
            lokales _, _, upstream_http_location = Zeichenfolge.find(ngx.var.upstream_http_location, "^http:/(.*)$")
            ngx.header["zzzz"] = "/proxy-to" .. upstream_http_location
            ngx.exec("/proxy-to" .. upstream_http_location);
        ';
    }
}

Im Vergleich zur vorherigen Änderung besteht der einzige Unterschied im Hinzufügen einer Proxy_intercept_errors-Direktive. Die Testergebnisse lauten wie folgt:

curl -I "http://192.168.109.128/flv.bn.netease.com/tvmrepo/2014/8/5/P/EA3I1J05P/SD/EA3I1J05P-mobile.mp4" -L 
HTTP/1.1 302 vorübergehend verschoben
Server: nginx/1.4.6
Datum: Montag, 25. August 2014, 15:05:54 GMT
Inhaltstyp: text/html
Inhaltslänge: 160
Verbindung: Keep-Alive
zzzz: /proxy-to/183.61.140.24/flv.bn.netease.com/tvmrepo/2014/8/5/P/EA3I1J05P/SD/EA3I1J05P-mobile.mp4

Diesmal ist es noch magischer. Es gibt direkt einen 302-Status zurück und springt nicht weiter.

Das Problem besteht darin, dass die erste 302-Anforderung zwar erfolgreich @error_page_302 eingibt, die nachfolgenden error_page-Anweisungen jedoch nicht funktionieren. Das heißt, error_page überprüft nur den vom Backend zum ersten Mal zurückgegebenen Statuscode und überprüft nachfolgende Backend-Statuscodes nicht weiter.

Überprüfen Sie die Informationen. Zu diesem Zeitpunkt ist ein weiterer Befehl „recursive_error_pages“ hilfreich.

4. Dritte Revision

Server {
    hören Sie 80;
    proxy_intercept_errors ein;
    rekursive_Fehlerseiten ein;
    Standort / {
        umschreiben_von_lua '
            ngx.exec("/proxy-to" .. ngx.var.request_uri)
        ';
    }
    Standort ~ /proxy-to/([^/]+)(.*) {
        Proxy-Passwort http://$1$2$ist_Argumente$Abfragezeichenfolge;
        Fehlerseite 302 = @Fehlerseite_302;

    }
    Standort @error_page_302 {
        umschreiben_von_lua '
            lokales _, _, upstream_http_location = Zeichenfolge.find(ngx.var.upstream_http_location, "^http:/(.*)$")
            ngx.header["zzzz"] = "/proxy-to" .. upstream_http_location
            ngx.exec("/proxy-to" .. upstream_http_location);
        ';
    }
}

Im Vergleich zum letzten Mal wurde lediglich die On-Anweisung „recursive_error_pages“ hinzugefügt. Die Testergebnisse lauten wie folgt:

curl -I "http://192.168.109.128/flv.bn.netease.com/tvmrepo/2014/8/5/P/EA3I1J05P/SD/EA3I1J05P-mobile.mp4" -L 
HTTP/1.1 200 OK 
Server: nginx/1.4.6 
Datum: Montag, 25. August 2014, 15:09:04 GMT 
Inhaltstyp: video/mp4 
Inhaltslänge: 3706468 
Verbindung: Keep-Alive 
zzzz: /proxy-to/14.18.140.83/f48bad0100000000-1408984745-236096587/data6/flv.bn.netease.com/tvmrepo/2014/8/5/P/EA3I1J05P/SD/EA3I1J05P-mobile.mp4 
Letzte Änderung: Montag, 25. August 2014, 00:21:07 GMT 
Cache-Steuerung: kein Cache 
ETag: "53fa8173-388e64" 
NG: CHN-MM-4-3FE 
X-Mod-Name: Mvod-Server/4.3.3 
Akzeptierte Bereiche: Bytes

Es ist ersichtlich, dass Nginx schließlich erfolgreich 200 zurückgegeben hat. An diesem Punkt spielt Nginx tatsächlich die Rolle eines Proxys, indem es die mehreren 302-Links einer Anfrage verbirgt und nur ein Endergebnis an den Client zurückgibt.

5. Zusammenfassung

Zusammenfassend können Sie durch die gemeinsame Verwendung der Anweisungen proxy_pass, error_page, proxy_intercept_errors und recursive_error_pages die Umleitungsdetails einer Anforderung vor dem Client verbergen und dem Benutzer direkt ein Endergebnis mit einem Statuscode von 200 zurückgeben.

Das Obige ist der vollständige Inhalt dieses Artikels. Ich hoffe, er wird für jedermanns Studium hilfreich sein. Ich hoffe auch, dass jeder 123WORDPRESS.COM unterstützen wird.

Das könnte Sie auch interessieren:
  • Detaillierte Erläuterung des Problems beim Abrufen einer echten IP basierend auf dem Nginx-Reverse-Proxy
  • Python-Implementierungsbeispiel zum Abrufen der IP-Adresse und der Verkehrsstatistik des Nginx-Servers
  • Detaillierte Erläuterung der Konfiguration von Nginx zum Abrufen der Benutzer-IP bei Verwendung der CDN-Beschleunigung
  • Detaillierte Erläuterung der drei Möglichkeiten zum Konfigurieren virtueller Nginx-Hosts (basierend auf IP)
  • So stellen Sie mit Nginx mehrere Vue-Projekte unter demselben Domänennamen bereit und verwenden einen Reverse-Proxy
  • Der Reverse-Proxy-Dienst von Nginx verursacht beim Zugriff auf Ressourcen aufgrund eines Fehlers in der Konfigurationsdatei einen 404-Fehler
  • Detaillierte Erläuterung des Prozesses, mit dem Nginx die echte Quell-IP erhält, nachdem mehrere Proxy-Ebenen durchlaufen wurden

<<:  Detaillierte Erklärung der allgemeinen For-Schleife in JavaScript-Anweisungen

>>:  So melden Sie sich unter Shell schnell ohne Kennwort bei der MySQL-Datenbank an

Artikel empfehlen

Erläuterung des Problems bei der Auswahl des MySQL-Speicherzeittyps

Der datetime-Typ wird normalerweise zum Speichern...

JavaScript imitiert die Spezialeffekte der Jingdong-Lupe

In diesem Artikel wird der spezifische Code von J...

So implementieren Sie Zeilenumbrüche im Texteingabebereich von Textarea

Wenn Sie den Text im Textarea-Eingabebereich umbre...

Sonderzeichen in HTML anzeigen (mit Sonderzeichen-Korrespondenztabelle)

Reproduktion des Problems Beim Bearbeiten mit HTM...

MySQL-Lösung für zeitgesteuerte Backups (mithilfe von Linux crontab)

Vorwort Obwohl manche Liebe auf dieser Welt ihren...

Analyse des Hintergrundauthentifizierungsprozesses von Vue-Elementen

Vorwort: Kürzlich stieß ich in meinem Projekt auf...

Vue realisiert die Funktion eines Bucheinkaufswagens

In diesem Artikelbeispiel wird der spezifische Co...

Beheben Sie den Fehler beim Löschen von MySQL-Benutzern

Als der Autor MySQL zum Hinzufügen eines Benutzer...

So installieren Sie Docker auf Raspberry Pi

Da Raspberry Pi auf der ARM-Architektur basiert, ...

Ein Beispiel für die Implementierung eines adaptiven Quadrats mit CSS

Die traditionelle Methode besteht darin, ein Quad...

JavaScript, um einen einheitlichen Animationseffekt zu erzielen

In diesem Artikelbeispiel wird der spezifische Co...