代码之家  ›  专栏  ›  技术社区  ›  Robert Kitching

NGINX反向代理背后的ASP.NET MVC

  •  2
  • Robert Kitching  · 技术社区  · 6 年前

    我目前正在做一个项目,它要求我们当前的一个ASP.NET MVC5 web应用程序位于客户端将控制的NGINX反向代理后面。

    我是新来的NGINX,所以缺乏知识。

    反向代理将放置在子路径上。(以下示例)

    http://localhost:9999/foo/bar/

    然后,这将代理到MVC5应用程序的根目录(端口9998),我已经在本地设置NGINX来测试该站点是否会按预期工作。我们使用到资源的绝对路径(托管在内部CDN中),因此所有这些负载都如预期的那样。

    我的问题 -反向代理正常工作并显示应用程序的根页。当点击使用this.RedirectToAction()或@html.ActionLink()等创建的任何控制器方法/页面链接时,问题开始出现。

    MVC应用程序没有意识到它是在反向代理后面运行的,并将子路径从其派生的URL中剥离出来。

    所以重定向到主控制器看起来像

    http://localhost:9999/home

    而不是:

    http://localhost:9999/foo/bar/home

    有人有什么想法可以抵消这一点吗?我可以看到.NET core有一个解决方案,但看不到MVC5的任何东西。我可以使用this.Redirect()并指定绝对路径,但应用程序很大,在没有反向代理的情况下用于其他场景。

    这可以通过我的NGINX配置解决吗?我的配置如下:

    #user  nobody;
    worker_processes  1;
    
    events {
    worker_connections  1024;
    }
    
    http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    
    
    keepalive_timeout  65;
    
    server {
        listen       9999;
        server_name  localhost;
    
        location /foo/bar/ {
    
            rewrite ^/foo/bar/(.*)$ /$1 break;
            proxy_pass  http://127.0.0.1:9998/;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
    
    }
    }
    
    2 回复  |  直到 6 年前
        1
  •  0
  •   Walter    6 年前

    您可以使用UsePathBase代码,如:

     app.UsePathBase($"ApplicationFolder").UseMvc(routes =>
                    {
                         routes.MapRoute(
                               "default", GetDefaultRoutePath());
                    });
    
        2
  •  0
  •   Robert Kitching    6 年前

    我现在找到了两个解决方案。。。

    我选择了 解决方案二 因为它不需要代码更改,但是已经成功地测试了这两个解决方案

    解决方案一

    抱歉,我无法访问这台机器上的工作测试代码,但它如下所示:

    1. 创建一个基本控制器并重写ControllerBase.RedirectToAction方法。
    2. 将基本URL设置添加到webconfig(或db设置等)。
    3. 创建自定义重定向结果对象并将baseurl附加到URL。从重写的方法返回自定义结果对象。

      protected override RedirectToRouteResult RedirectToAction(string actionName, string controllerName, RouteValueDictionary routeValues)
      

    解决方案二

    使用IIS,在虚拟目录或子应用程序中运行应用程序以匹配代理的位置。MVC将自动正确地控制所有路由,而不必重写任何基本方法。

    注意。您需要像对待任何代理一样小心对待任何相对路径/链接。

    我目前在生产中使用这种方法没有任何问题。请参见下面的示例。

    Example