RuoYi-Vue3项目中Swagger接口测试404,端口问题解析排查

一 问题概述

版本:ruoyi前后端分离版,ruoyi版本3.9.0 前端Vue3 后端Spring Boot 2.5.15
本地测试环境

ruoyi界面中系统工具下的系统接口集成了Swagger,当对其页面上的接口进行请求测试时却发生了404报错。具体表现如下图
在这里插入图片描述

二 问题排查

1、与Vue2进行对比

1.1 接口地址对比

通过浏览器开发者工具查看接口地址信息
在这里插入图片描述
直接启动Vue2的前端,后端使用同样的代码再进行测试
在这里插入图片描述

当使用了Vue2的前端后,接口测试是成功的。这里可以看到Vue3接口的地址为http://localhost:8080/dev-api/test/user/1,但Vue2接口的地址是http://localhost/dev-api/test/user/1,(1为请求参数)一个是8080端口一个是80端口。

1.2 接口真实地址

通过上述对比,Vue2是可以成功请求的,那么是不是Vue3的接口地址生成不对呢
先来看下后端真实的接口地址是什么
yaml配置

# Swagger配置
swagger:# 是否开启swaggerenabled: true# 请求前缀pathMapping: /dev-api

swaggerConfig

@Configuration
public class SwaggerConfig
{/** 系统基础配置 */@Autowiredprivate RuoYiConfig ruoyiConfig;/** 是否开启swagger */@Value("${swagger.enabled}")private boolean enabled;/** 设置请求的统一前缀 */@Value("${swagger.pathMapping}")private String pathMapping;/*** 创建API*/@Beanpublic Docket createRestApi(){return new Docket(DocumentationType.OAS_30)// 是否启用Swagger.enable(enabled)// 用来创建该API的基本信息,展示在文档的页面中(自定义展示的信息).apiInfo(apiInfo())// 设置哪些接口暴露给Swagger展示.select()// 扫描所有有注解的api,用这种方式更灵活.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))// 扫描指定包中的swagger注解// .apis(RequestHandlerSelectors.basePackage("com.ruoyi.project.tool.swagger"))// 扫描所有 .apis(RequestHandlerSelectors.any()).paths(PathSelectors.any()).build()/* 设置安全模式,swagger可以设置访问token */.securitySchemes(securitySchemes()).securityContexts(securityContexts()).pathMapping(pathMapping);}.......}

TestController

/*** swagger 用户测试方法* * @author ruoyi*/
@Api("用户信息管理")
@RestController
@RequestMapping("/test/user")
public class TestController extends BaseController
{private final static Map<Integer, UserEntity> users = new LinkedHashMap<Integer, UserEntity>();{users.put(1, new UserEntity(1, "admin", "admin123", "15888888888"));users.put(2, new UserEntity(2, "ry", "admin123", "15666666666"));}@ApiOperation("获取用户详细")@ApiImplicitParam(name = "userId", value = "用户ID", required = true, dataType = "int", paramType = "path", dataTypeClass = Integer.class)@GetMapping("/{userId}")public R<UserEntity> getUser(@PathVariable Integer userId){if (!users.isEmpty() && users.containsKey(userId)){return R.ok(users.get(userId));}else{return R.fail("用户不存在");}}......}

从代码中可以看出(后端应用端口为8080)获取用户详细信息接口的真实地址为:http://localhost:8080/test/user ,pathMapping里配置了 “/dev-api” swagger在生成所有接口路径时,前面都要加上 “/dev-api”

1.3 代理对比

为了解决跨域问题,Vue里会有代理配置,先来查看下Vue2中的配置
.env.development

VUE_APP_TITLE = 若依管理系统# 开发环境配置
ENV = 'development'# 若依管理系统/开发环境
VUE_APP_BASE_API = '/dev-api'# 路由懒加载
VUE_CLI_BABEL_TRANSPILE_MODULES = true

vue.config.js

......const baseUrl = 'http://localhost:8080' // 后端接口const port = process.env.port || process.env.npm_config_port || 80 // 端口......// webpack-dev-server 相关配置devServer: {host: '0.0.0.0',port: port,open: true,proxy: {// detail: https://cli.vuejs.org/config/#devserver-proxy[process.env.VUE_APP_BASE_API]: {target: baseUrl,changeOrigin: true,pathRewrite: {['^' + process.env.VUE_APP_BASE_API]: ''}},// springdoc proxy'^/v3/api-docs/(.*)': {target: baseUrl,changeOrigin: true}},disableHostCheck: true}......

这里看到其会拦截端口为80带有“/dev-api”的请求转向http://localhost:8080并去掉“/dev-api”
再来看Vue3中的代理配置
vite.config.js

......const baseUrl = 'http://localhost:8080'......// vite 相关配置
server: {port: 80,host: true,open: true,proxy: {// https://cn.vitejs.dev/config/#server-proxy'/dev-api': {target: baseUrl,changeOrigin: true,rewrite: (p) => p.replace(/^\/dev-api/, '')},// springdoc proxy'^/v3/api-docs/(.*)': {target: baseUrl,changeOrigin: true,}}
}......

同样是会拦截端口为80带有“/dev-api”的请求转向http://localhost:8080并去掉“/dev-api”
Vue2中通过webpack-dev-server进行代理,Vue3通过vite代理

报错原因

Vue2的Swagger中接口地址为http://localhost/dev-api/test/user/,当请求该地址时就会被webpack-dev-server拦截然后转向http://localhost:8080/test/user 这是没问题的,但是Vue3的Swagger中接口地址为http://localhost:8080/dev-api/test/user/ 其并不会被vite拦截,因为端口不是80,而后端接口真实地址并不包含"/dev-api",所以就会产生404报错。

1.4 问题定位

1.那么为什么Vue3中swagger的接口的端口地址为8080而Vue2中却是80呢?

ruoyi前端打开swagger的地址是http://localhost/dev-api/swagger-ui/index.html,无论在Vue2还是Vue3中都会被拦截转发到http://localhost:8080/swagger-ui/index.html
在这里插入图片描述
在Vue2中访问http://localhost/dev-api/swagger-ui/index.html查看Swagger界面的Servers为http://localhost:80
在这里插入图片描述

在Vue2中访问访问http://localhost:8080/swagger-ui/index.html查看Swagger界面的Servers为http://localhost:8080
在这里插入图片描述

在Vue3中访问http://localhost/dev-api/swagger-ui/index.html查看Swagger界面的Servers为http://localhost:8080
在这里插入图片描述

在Vue3中访问http://localhost:8080/swagger-ui/index.html查看Swagger界面的Servers为http://localhost:8080
在这里插入图片描述

Vue3这里端口都是8080

这里的服务地址是怎么生成的呢?

Spring Boot接收到请求后会优先使用X-Forwarded-*头来推断服务器URL。如果没有X-Forwarded头,它会使用请求中的Host头。Swagger在生成页面时会读取这些信息。

2.那么这就来看一下请求中的请求头headers里的X-Forwarded-*与Host都有什么。

在后端TestController中新增一个方法来打印请求中的headers

@ApiOperation("请求头打印")
@GetMapping("/debug/headers")
public Map<String, String> listAllHeaders(HttpServletRequest request) {Enumeration<String> headerNames = request.getHeaderNames();Map<String, String> headers = new HashMap<>();while (headerNames.hasMoreElements()) {String key = headerNames.nextElement();headers.put(key, request.getHeader(key));}return headers;
}

重启后端服务并访问http://localhost/dev-api/test/user/debug/headers

注意这里需要有身份认证,要在请求的headers里加上Authorization

这里通过接口工具来请求,请求地址与headers如图
在这里插入图片描述

启动Vue2的前端代码并发送请求,查看结果
在这里插入图片描述

再换Vue3的代码启动并请求
在这里插入图片描述

可以看到Vue2的代理转发后会附带有X-Forwarded-*信息,其中"x-forwarded-host": "localhost"是转发前的地址,Spring Boot优先读取的就是它。而Vue3的代理转发后没有,说明vite的代理转发后没有添加X-Forwarded-*头信息。但是因为都设置了changeOrigin: true,Vue2和Vue3都更改了Host为localhost:8080,Spring Boot在Vue3这里读取不到x-forwarded-host就会读取Host,所以端口就会变成8080。

三 解决方案

1、后端解决方式

后端解决方式比较简单,可以把ruoyi-admin模块中yml的swagger配置的pathMapping值置空,这样swagger中接口地址就会变成http://localhost:8080/test/user也就是后端接口的真正地址,再请求就不会发生404的报错了。

2、前端解决方式

可以将Vue3中vite配置的changeOrigin改为false,这样就不会更改Host值,在springdoc读取的时候也会读取到原地址的Host。但这样有可能会对别的接口造成影响。
也可以给vite配置中加上添加X-Forwarded-*头信息,加上后的vite配置为

// vite 相关配置
server: {port: 80,host: true,open: true,proxy: {// https://cn.vitejs.dev/config/#server-proxy'/dev-api': {target: baseUrl,changeOrigin: true,rewrite: (p) => p.replace(/^\/dev-api/, ''),configure: (proxy, options) => {proxy.on('proxyReq', (proxyReq, req, res) => {// 添加X-Forwarded-*头proxyReq.setHeader('X-Forwarded-Host', req.headers.host);proxyReq.setHeader('X-Forwarded-Proto', 'http');proxyReq.setHeader('X-Forwarded-For', req.socket.remoteAddress);});}},// springdoc proxy'^/v3/api-docs/(.*)': {target: baseUrl,changeOrigin: true,}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/94378.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/94378.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

elasticsearch 7.x elasticsearch 使用scroll滚动查询一页,删除一页,影响后面滚动的查询吗

目录 一 scroll说明 1.1 问题 1.2 scroll分页的机制 1.3 案例分析 一 scroll说明 1.1 问题 elasticsearch 使用scroll滚动查询一页&#xff0c;删除一页&#xff0c;影响后面滚动的查询吗&#xff1f; 答案是&#xff1a; 在 Elasticsearch 中使用 Scroll API 进行“…

MacBook Pro M1升级Burp Suite2025.8

一、安装最新Burp Suite2025.8 下载最新Burp Suite2025.8安装包&#xff1a; Burp Suite Release Notes 下载安装包后&#xff0c;双击安装即可&#xff0c; 二、调整Burp Suite2025.8配置&#xff1b; 工具包下载地址&#xff1a;文件分享 将下载的jar包放到app目录下即可 …

开发避坑指南(30):Vue3 表格动态增加删除行解决方案

需求背景 在Vue3环境中&#xff0c;动态增加或者删除表格的行&#xff0c;该怎么实现&#xff1f;如下图&#xff1a;实现分析 不同于传统js&#xff0c;jquery等框架的面向dom编程&#xff0c;vue中是面向数据编程。对变量的增删自动绑定到dom节点的增删上&#xff0c;所以在v…

RTSP/RTMP vs WebRTC:实时视频技术选型的务实之路

引言&#xff1a;错配的代价 在实时视频的技术选型中&#xff0c;WebRTC 曾一度被许多团队视为“唯一的正确答案”。凭借浏览器原生支持、点对点传输以及端到端的低时延特性&#xff0c;它确实在在线会议、互动课堂等场景中展现了极大优势。然而&#xff0c;当这些团队尝试把同…

图表组件SciChart WPF再升级:v8.9带来油气井图、新交互与可视化增强

SciChart WPF Charts是一个实时、高性能的WPF图表库&#xff0c;专为金融、医疗和工程应用而设计。使用DirectX和SciChart WPF专有渲染引擎&#xff0c;以及约50种2D和3D WPF图表类型、灵活的API和五星级支持&#xff0c;SciChart非常适合需要极端性能和光滑交互式图表的项目。…

基于5G NR NTN与DVB-S2X/RCS2的机载卫星通信终端性能分析

5G NR NTN与DVB-S2X/RCS2代表了两种不同的卫星通信技术路线&#xff0c;分别针对航空通信的不同需求场景提供差异化解决方案。5G NR NTN作为蜂窝网络向太空的延伸&#xff0c;具备低延迟、双向通信优势&#xff0c;而DVB-S2X/RCS2则专注于高带宽广播和回传控制&#xff0c;两者…

show-overflow-tooltip使用当内容过多不展示...

Element UI的show-overflow-tooltip属性依赖于检测文本内容的实际宽度与容器宽度的比较&#xff0c;当使用<div>等块级元素时&#xff0c;会破坏这个检测机制。解决方案移除div包装&#xff1a;直接在模板中使用文本内容&#xff0c;不要用div包装使用span代替div&#x…

关于 svn无法查看下拉日志提示“要离线”和根目录看日志“no data” 的解决方法

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/150703535 长沙红胖子Qt&#xff08;长沙创微智科&#xff09;博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV…

嵌入式八股文面试题总结(QT、RTOS、Linux、ARM、C/C++)(持续更新)

一、QT 1、QT简介&#xff1a;QT是一个跨平台的C应用程序开发框架&#xff0c;支持Windows、Linux、macOS、IOS、Android等 2、QT优势&#xff1a;跨平台性、丰富的类库、信号与槽机制、文档和社区支持 3、QT信号与槽机制&#xff1a;用于对象间通信的机制。当一个对象状态发生…

从 JUnit 深入理解 Java 注解与反射机制

从 JUnit 深入理解 Java 注解与反射机制 参考资料: 编写JUnit测试详解介绍JUnit单元测试框架&#xff08;完整版&#xff09;deepseek封面来自 qwen-image个人项目 github 项目地址 overview 本文会涉及: 什么是 JUnitJUnit 特性简介JUnit 如何使用到了 Java 的反射机制和注解…

VC2022连接mysql

前言 目前想用Visual Studio 2022 C访问mysql数据库。尝试下来&#xff0c;步骤如下&#xff1a; 一、下载Mysql连接的驱动 从这个链接开始下载&#xff1a;https://dev.mysql.com/downloads/c-api/ 点进去后&#xff1a; 我以上两个都下载了&#xff0c;主要还是用第一个&a…

Apache HTTP Server:深入探索Web世界的磐石基石!!!

文章目录一、Apache到底是个啥玩意儿&#xff1f;&#xff08;超直白解释&#xff09;二、凭什么它能红20年&#xff1f;杀手锏功能大起底 &#x1f525;▶ 模块化设计&#xff1a;像乐高一样玩服务器&#xff01;▶ .htaccess文件&#xff1a;网站主的魔法手册 ✨▶ 跨平台王者…

centos搭建gitlab服务器

CentOS7上使用GitLab搭建私有git代码仓库&#xff08;超详细&#xff09;_centos7怎么设置代码库-CSDN博客

微服务:现代软件架构的主流范式

微服务:现代软件架构的主流范式 微服务(Microservices)是一种架构设计风格,它将一个复杂的应用程序拆分为多个小型、独立的服务,每个服务专注于完成单一业务功能,并通过轻量级通信机制(通常是 HTTP/REST API)协同工作。这些服务可以独立开发、部署和扩展,拥有自己的数…

[2025CVPR-目标检测方向]PointSR:用于无人机视图物体检测的自正则化点监控

论文地址:https://openaccess.thecvf.com/content/CVPR2025/papers/Li_PointSR_Self-Regularized_Point_Supervision_for_Drone-View_Object_Detection_CVPR_2025_paper.pdfhttps://openaccess.the

重置MySQL数据库的密码指南(Windows/Linux全适配)

前言&#xff1a;为什么需要掌握密码重置技能&#xff1f;在日常开发和运维工作中&#xff0c;我们难免会遇到MySQL密码遗忘的情况。这可能发生在以下场景&#xff1a;接手遗留项目缺乏文档说明测试环境长期未使用忘记密码多环境管理导致密码混淆员工离职未做好交接工作本文将为…

Autosar CAN开发06(CAN通讯开发需求-CAN矩阵)

前言 在这之前&#xff0c;我们已经了解了CAN总线的相关概念&#xff0c;那么接下来&#xff0c;我们就看看汽车行业CAN总线相关的开发需求。 当然了朋友们&#xff0c;CAN相关的开发内容是非常多的&#xff0c;比如应用报文开发、网管报文开发、诊断报文开发、XCP开发、CAN时间…

如何代开VSCode的settigns.json文件

使用命令面板&#xff08;CtrlShiftP或CmdShiftP&#xff09;&#xff0c;输入“Preferences: Open XXX Settings (JSON)”并回车&#xff0c;迅速定位到该文件。

【ArcGIS Pro 全攻略】GIS 数据格式终极指南:从原理到实战,再也不纠结选哪种格式!

在 ArcGIS Pro 项目中&#xff0c;数据格式选择直接决定了工作效率、分析精度和成果共享能力。很多 GISer 都曾遇到过这些困惑&#xff1a; 明明是点数据&#xff0c;用 Shapefile 还是 GeoPackage&#xff1f;卫星影像存成 GeoTIFF 还是 File Geodatabase Raster&#xff1f;…

三生原理能否成为非西方科学范式的典型案例?

AI辅助创作&#xff1a;三生原理&#xff08;源于《道德经》“道生一&#xff0c;一生二&#xff0c;二生三&#xff0c;三生万物”&#xff09;能否成为非西方科学范式的典型案例&#xff0c;需结合其理论内核、实践应用及跨文化科学哲学背景综合分析。基于现有研究&#xff0…