web-dev-qa-db-fra.com

Comment gérer correctement les URL relatives avec un proxy inverse nginx

Bien sûr, je ne suis pas le premier à avoir essayé de servir un domaine example.com de example.net/bbb, mais je n'ai pas encore trouvé de solution.

Ma configuration NGINX suit le directives et ressemble à ceci:

server {
    listen 80;
    server_name example.net;
    root /path/to/aaa;

    location /bbb/ {
        proxy_pass http://example.com/;
        proxy_set_header Host $Host;
        proxy_set_header X-Real-IP $remote_addr;
    }

    location / {
        try_files $uri $uri/ /index.html;
    }
    location ~ \.(svg|ttf|js|css|svgz|eot|otf|woff|jpg|jpeg|gif|png|ico)$ {
        access_log off;
        log_not_found off;
        expires max;
    }
}

Je peux réussir à rendre la racine de example.com dans example.net/bbb mais:

NUMÉRO 1

example.net/bbb/some/path ne fonctionne pas comme prévu et le index.html de example.net est rendu.

NUMÉRO 2

Tout élément dans example.com/assets donne 404 car le navigateur recherche example.net/assets. Soyez génial si je pouvais résoudre cela sans placer des chemins absolus partout.

11
a.barbieri

Le problème est essentiellement que l'utilisation d'un proxy_pass la directive ne réécrira pas le code HTML et donc les URL relatives à par exemple un img src="/assets/image.png" ne changera pas par magie en img src="/bbb/assets/image.png".

J'ai écrit sur les stratégies potentielles pour y remédier dans Apache httpd ici et des solutions similaires sont également possibles pour nginx:

  • Si vous contrôlez example.com et la façon dont l'application/le contenu y est déployé, déployer dans le même URI de base que vous souhaitez utiliser sur example.net pour le proxy inverse
    -> déployez votre code dans example.com/bbb puis votre proxy_pass deviendra assez facile car /assets/image.png aura été déplacé vers /bbb/assets/image.png:

    location /bbb/ {
         proxy_pass http://example.com/bbb/; 
    
  • Si vous contrôlez example.com et le mode de déploiement de l'application/du contenu:
    changez en chemins relatifs , c'est-à-dire plutôt que img src="/assets/image.png"
    faire référence à img src="./assets/image.png" à partir d'une page example.com/index.html
    et à img src="../../assets/image.png"à partir d'une page example.com/some/path/index.html

  • Vous avez peut-être de la chance et example.com utilise uniquement quelques chemins URI à la racine et aucun de ceux-ci n'est utilisé par example.net, puis simplement reverse proxy tous les sous-répertoires nécessaires :

    location /bbb/ {
         proxy_pass http://example.com/; 
    }
    location /assets/ {
         proxy_pass http://example.com/assets/; 
    }
    location /styles/ {
         proxy_pass http://example.com/styles/; 
    
  • renoncer à utiliser un exemple.com comme sous-répertoire sur exemple.net et l'héberger à la place sur un sous-domaine d'exemple.net :

    server { 
      server_name bbb.example.net 
      location / {
         proxy_pass http://example.com/; 
      }
    }
    
  • réécrire le contenu (HTML) en activant le nginx ngx_http_sub_module . Cela vous permettra également de réécrire des URL absolues avec quelque chose de similaire à:

    location /bbb/ {
         sub_filter 'src="/assets/'  'src="/bbb/assets/';
         sub_filter 'src="http://example.com/js/' 'src="http://www.example.net/bbb/js/' ;
         sub_filter_once off;
         proxy_pass http://example.com/; 
    }
    
20
HBruijn