社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  NGINX

Asp.Net Core Swagger 页面适配 Nginx 二级目录 | 完美解决方案

dotNET跨平台 • 4 年前 • 560 次点击  

前言

当我们把 Asp.Net Core 程序部署在 Nginx 后面时,通常来说,不会使用顶级目录,而是使用二级目录,访问方式类似:

http://{DOMAIN}/{BASEPATH}/WeatherForecast

Ngix 配置

假设 Nginx 开放端口8000,二级目录设为 demo,Asp.Net Core 程序实际访问地址为 http://localhost:5000/。

则 Ngix 配置如下:

server {
    listen       8000;
    server_name  localhost;

    location /demo/ {
        proxy_pass   http://localhost:5000/;
    }
}

可以看到可以正常访问API:

但是,打开swagger页面时,会提示找不到/swagger/v1/swagger.json

常规方案

百度了一下,找到了所谓的“完美解决方案”:

他是使用app.UsePathBase方法,设置站点请求基础路径,也就是说 Asp.Net Core 程序实际访问地址也是带二级目录的:

这种方案当然可以实现需求,但是远远谈不上“完美”——如果修改 Nginx 二级目录设置,还要同步修改 Asp.Net Core 配置,而且还要保证二者名称完全相同。

我的方案

1.解决相对路径问题

首先,我们分析,为什么找不到/swagger/v1/swagger.json文件。

其实,这是因为如果 url 以“/”开头,浏览器会从请求的根目录开始查找,从错误提示也可以看出:

我们可以去掉“/”,让浏览器从发起请求的路径开始查找。

通过 Referer 请求头,我们可以知道发起请求的路径是/demo/swagger/

因此,我们只需要修改成如下相对路径即可:




    
app.UseSwaggerUI(c => c.SwaggerEndpoint("v1/swagger.json""WebApplication1 v1"));

2.解决服务根地址问题

上面解决了 swagger.json 访问问题,但是在 swagger 中测试 API 时,会提示 404:

这是因为 swagger 并不知道 API 路径需要增加二级目录。

如果采用“完美解决方案”中的方式,使用配置指定二级目录,那又回到老路上去了:

其实,Nginx 转发请求时,是知道原始请求地址的,我们只需要将原始请求地址告诉 swagger。

首先,修改 Ngix 配置:

location /demo/ {
    proxy_pass   http://localhost:5000/;
    proxy_set_header X-Request-Uri $request_uri;
}

然后,由 swagger 来分析出二级目录即可,不需要增加任何配置:

app.UseSwagger(options =>
{
    options.PreSerializeFilters.Add((swagger, httpReq) =>
    {
        if (httpReq.Headers.ContainsKey("X-Request-Uri"))
        {
            var index = httpReq.Headers["X-Request-Uri"].ToString().IndexOf("/swagger/");
            if (index > 0)
            {
                var serverUrl = $"{httpReq.Headers["X-Request-Uri"].ToString().Substring(0, index)}/";
                swagger.Servers = new List { new OpenApiServer { Url = serverUrl } };
            }
        }
    });
});

结论

我们的实现方案,相对网上找到的“完美解决方案”,需要配置的地方更少,而且更加灵活,对开发环境不会产生任何影响和变动。

想了解更多内容,请关注我的个人公众号”My IO“

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/128748