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
英文地址,請注明出處:http://en.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…