web-dev-qa-db-fra.com

Intercepter les redirections backend 301/302 (proxy_pass) et réécrire dans un autre bloc d'emplacement possible?

Nous avons un couple de backends assis derrière nos frontaux nginx.

Est-il possible d'intercepter les redirections 301/302 envoyées par ces serveurs et que nginx les gère?

Nous étions quelque chose seul les lignes de:

error_page 302 = @target;

Mais je doute que les redirections 301/302 puissent être traitées de la même façon que 404, etc., etc. Je veux dire, error_page ne s'applique probablement pas à 200, etc. codes d'erreur?

Donc, pour résumer:

Nos backends renvoient 301/302 de temps en temps. Nous aimerions que nginx les intercepte et les réécrit dans un autre bloc d’emplacement, où nous pourrions faire beaucoup d’autres choses avec eux.

Possible?

Merci!

17
anonymous-one

Vous pouvez utiliser la directive proxy_redirect:

http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_redirect

Nginx retournera toujours 301/302 au client, mais proxy_redirect modifiera l'en-tête Location et le client devra faire une nouvelle demande à l'URL indiquée dans l'en-tête Location.

Quelque chose comme ceci devrait faire la demande suivante à nginx:

proxy_redirect http://upstream:port/ http://$http_Host/;

16
Tuomo Kestilä

J'ai réussi à résoudre un cas plus générique lorsqu'un emplacement de redirection peut être une URL externe.

server {
    ...

    location / {
        proxy_pass http://backend;
        # You may need to uncomment the following line if your redirects are relative, e.g. /foo/bar
        #proxy_redirect / /;
        proxy_intercept_errors on;
        error_page 301 302 307 = @handle_redirects;
    }

    location @handle_redirects {
        set $saved_redirect_location '$upstream_http_location';
        proxy_pass $saved_redirect_location;
    }
}

ServerFault répond à cette question: https://serverfault.com/questions/641070/nginx-302-redirect-resolve-internally

4
Vlad Frolov

Plus sur proxy_redirect, pour les emplacements relatifs

Cas

location /api/ {
  proxy_pass http://${API_Host}:${API_PORT}/;
}
  • le serveur redirige vers un emplacement relatif, sans le préfixe /api/
  • le navigateur suit la redirection et frappe un mur d'incompréhension

Solution

location /api/ {
  proxy_pass http://${API_Host}:${API_PORT}/;
  proxy_redirect ~^/(.*) http://$http_Host/api/$1;
}
0
Arnaud P