1

Asp.Net Core Swagger 页面适配 Nginx 二级目录 | 完美解决方案 #yyds干货盘点#

 2 years ago
source link: https://blog.51cto.com/MyIO/5115649
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

当我们把 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:

Asp.Net Core Swagger 页面适配 Nginx 二级目录 | 完美解决方案 #yyds干货盘点#_二级

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

Asp.Net Core Swagger 页面适配 Nginx 二级目录 | 完美解决方案 #yyds干货盘点#_asp.net_02

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

Asp.Net Core Swagger 页面适配 Nginx 二级目录 | 完美解决方案 #yyds干货盘点#_nginx_03

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

Asp.Net Core Swagger 页面适配 Nginx 二级目录 | 完美解决方案 #yyds干货盘点#_二级_04

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

​1.解决相对路径问题​

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

其实,这是因为如果 url 以“/”开头,浏览器会从请求的根目录开始查找,从错误提示也可以看出:Asp.Net Core Swagger 页面适配 Nginx 二级目录 | 完美解决方案 #yyds干货盘点#_nginx_05

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

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

Asp.Net Core Swagger 页面适配 Nginx 二级目录 | 完美解决方案 #yyds干货盘点#_asp.net_06

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

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

Asp.Net Core Swagger 页面适配 Nginx 二级目录 | 完美解决方案 #yyds干货盘点#_asp.net_07

​2.解决服务根地址问题​

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

Asp.Net Core Swagger 页面适配 Nginx 二级目录 | 完美解决方案 #yyds干货盘点#_asp.net_08

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

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

Asp.Net Core Swagger 页面适配 Nginx 二级目录 | 完美解决方案 #yyds干货盘点#_asp.net_09

​​其实,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<OpenApiServer> { new OpenApiServer { Url = serverUrl } };
}
}
});
});

Asp.Net Core Swagger 页面适配 Nginx 二级目录 | 完美解决方案 #yyds干货盘点#_nginx_10

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

Asp.Net Core Swagger 页面适配 Nginx 二级目录 | 完美解决方案 #yyds干货盘点#_nginx_11

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

Asp.Net Core Swagger 页面适配 Nginx 二级目录 | 完美解决方案 #yyds干货盘点#_asp.net_12


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK