【问题标题】:How do I make an nginx proxy stop redirecting to root?如何让 nginx 代理停止重定向到 root?
【发布时间】:2016-09-08 19:30:39
【问题描述】:

我有一个节点应用程序在 nginx 的子目录中作为代理运行。我在重定向到应用程序本身的不同部分时遇到问题。它们总是重定向到根目录而不是代理的子目录。

示例:

如果我的应用代理位于 https://example.com/myApp/ 并且它重定向到 /admin/ 我希望页面重定向到 https://example.com/myApp/admin/ 而不是 https://example.com/admin/


这是我配置的相关部分:

  location /myApp {
    rewrite /myApp(.*) $1 break;

    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $host;
    proxy_set_header X-NginX-Proxy true;

    proxy_pass http://localhost:3030;
    proxy_redirect http://localhost:3030/ /myApp/;
  }

我也尝试将proxy_redirect 设置为(^|^http://localhost:3030)/ /myApp/;


这是该域的完整配置文件:

upstream php-handler {
  #server 127.0.0.1:9000;
  server unix:/var/run/php5-fpm.sock;
}

## HTTP
server {
  listen 80 default_server;
  listen [::]:80 default_server ipv6only=on;
  server_name example.com www.example.com;
  return 301 https://$server_name$request_uri;
}

## HTTPS
server {
  listen 443 ssl;
  server_name example.com;

  ssl_certificate /etc/ssl/www.example.com.crt;
  ssl_certificate_key /etc/ssl/www.example.com.key;

  add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;";
  add_header X-Content-Type-Options nosniff;
  add_header X-Frame-Options "SAMEORIGIN";
  add_header X-XSS-Protection "1; mode=block";

  root /var/www/example.com/;
  index index.html index.php;

  client_max_body_size 500M;
  fastcgi_buffers 64 4k;
  gzip on;

  # Website
  location / {
    try_files $uri $uri/ =404;

    location ~ \.php$ {
      fastcgi_split_path_info ^(.+\.php)(/.+)$;
      fastcgi_pass unix:/var/run/php5-fpm.sock;
      fastcgi_index index.php;
      include fastcgi_params;
    }

  }

  # My App
  location /myApp {
    rewrite /myApp(.*) $1 break;

    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $host;
    proxy_set_header X-NginX-Proxy true;

    proxy_pass http://localhost:3030;
    proxy_redirect http://localhost:3030/ /myApp/;

  }

【问题讨论】:

    标签: redirect nginx proxy


    【解决方案1】:

    好吧,我自己想通了。

    tl;博士:

    这行得通:

    proxy_redirect ~(^http://localhost:3030|^)/(.*)$ /myApp/$2;
    

    第一个选项:

    proxy_redirect / /myApp/;
    

    我猜这是可行的,因为应用程序重定向到 /admin/ 而不是 http://localhost:3030/admin/。但是,这并不能提供我正在寻找的灵活性。


    第二个选项:

    使用正则表达式

    所以当我尝试像这样使用正则表达式时,我最初犯了几个错误:

    proxy_redirect (^|^http://localhost:3030)/ /myApp/;
    

    首先,如果您要使用正则表达式,则需要以~ 开头以区分大小写或以~* 开头以不区分大小写。

    其次,当您使用正则表达式时,它显然会替换完整路径,而不仅仅是匹配的部分。例如,如果您要像这样设置 proxy_redirect:

    proxy_redirect ~/(a|b)/ /myApp/;
    

    如果您随后重定向到/a/some-subdirectory/,重写将导致/myApp/ 而不是/myApp/some-subdirectory/。要完成这项工作,您需要捕获路径的末尾并将其插入到重写的末尾,如下所示:

    proxy_rewrite ~/(a|b)/(.*)$ /myApp/$2;
    

    注意:我在文档中找不到有关此行为的任何信息。我只是根据自己的试验和错误的结果得出这个结论。


    所以我最终的 proxy_redirect 看起来像这样:

    proxy_redirect ~(^http://localhost:3030|^)/(.*)$ /myApp/$2;
    

    【讨论】:

      【解决方案2】:

      在我看来,你应该尝试在 server 块中的 listen 指令将其定义为默认值(来源:http://nginx.org/en/docs/http/request_processing.html):

      listen       80  
      
      default_server;
      

      以下声明表示无效的服务器名称(来源:http://nginx.org/en/docs/http/server_names.html)(因此它永远不会与您的任何有效域相交):

      Server_name _; 
      

      要解决您的问题,请确保您有一个带有监听(端口)和 server_name(虚拟主机)的服务器块 - 当您在使用虚拟主机名时从“更精确到更不精确”时,将首先触发这个块在 nginx 中匹配:

      Listen 80 
      
      Server_name your-domain-name.com;
      

      【讨论】:

      • 我不确定我是否理解您的意思。我的位置块嵌套在域的服务器块内。你说不应该?我将添加域的其余配置以防止混淆。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-02-28
      • 1970-01-01
      • 2021-04-06
      • 2016-04-11
      • 2021-10-13
      • 2019-03-12
      • 2015-11-29
      相关资源
      最近更新 更多