者:boot-react SinglePageAppConfig pushState 資源解析器深度剖析)
SPA 刷新 404 難題終結(jié)者boot-react SinglePageAppConfig pushState 資源解析器深度剖析【免費下載鏈接】boot-reactA starter application with spring boot and react項目地址: https://gitcode.com/gh_mirrors/bo/boot-reactboot-react是一個基于 Spring Boot React 的單頁應(yīng)用SPA啟動器項目其核心類SinglePageAppConfig實現(xiàn)了一個pushState 資源解析器從根源上解決了 SPA 應(yīng)用中刷新頁面 404這一經(jīng)典難題讓 React Router 的 History 模式在后端服務(wù)器上也能完美工作。 為什么 SPA 刷新頁面會 404先搞懂問題本質(zhì)才能理解解決方案的巧妙之處。場景用戶操作瀏覽器實際請求結(jié)果正常點擊導航點私有頁鏈接無請求JS 內(nèi)部跳轉(zhuǎn)? 頁面正常刷新頁面在/private按 F5GET /private? 服務(wù)器返回 404React Router 默認使用瀏覽器的History APIpushState來生成/login、/private這類干凈的 URL。URL 變化時并沒有真正向后端發(fā)起請求所以平時一切正常。但一旦刷新頁面瀏覽器會帶著完整 URL 向服務(wù)器發(fā)真實請求。而服務(wù)器上根本不存在名為private的文件或接口——它只是前端路由于是服務(wù)器一臉懵地返回 404。 核心矛盾前端路由是虛擬的而 HTTP 請求是真實的。boot-react 的前端路由定義在frontend/src/router/router.js中包含/首頁列表、/private需登錄的私有頁見frontend/src/router/privateRoute.js、/login、/logout等路由。? boot-react 的雙環(huán)境解決方案boot-react 針對開發(fā)和生產(chǎn)兩個環(huán)境分別做了處理思路殊途同歸把所有找不到真實文件的請求統(tǒng)統(tǒng)回退fallback到index.html再交給 React Router 接管。開發(fā)環(huán)境connect-history-api-fallback開發(fā)時前端由獨立的 Express 開發(fā)服務(wù)器托管項目用一行代碼引入中間件 connect-history-api-fallback 實現(xiàn)回退frontend/server.js同時/api開頭的請求被代理到后端的localhost:8080實現(xiàn)前后端聯(lián)調(diào)零配置。生產(chǎn)環(huán)境SinglePageAppConfig 登場生產(chǎn)環(huán)境中前端構(gòu)建產(chǎn)物index.html 打包后的 JS/CSS會被打進 Spring Boot 的 jar 包由 Spring MVC 的靜態(tài)資源處理器統(tǒng)一分發(fā)。boot-react 通過SinglePageAppConfig類注冊了一個自定義資源解析器源碼位于backend/src/main/java/react/config/SinglePageAppConfig.java 深度剖析pushState 資源解析器的工作流程SinglePageAppConfig繼承WebMvcConfigurerAdapter攔截所有路徑/**并把靜態(tài)資源指向classpath:/static/最后掛上一個內(nèi)部類PushStateResourceResolver。它的決策邏輯非常清晰只需三步是 API 請求嗎路徑在忽略列表api中 → 不處理交還給 REST 接口是靜態(tài)資源嗎路徑擴展名命中白名單js、css、html、png、svg、woff等 14 種→ 去static目錄找真實文件都不是→ 判定為前端路由直接返回index.html核心解析方法resolve()的邏輯示意如下private Resource resolve(String requestPath, List? extends Resource locations) { if (isIgnored(requestPath)) { // /api/** 交給后端 return null; } if (isHandled(requestPath)) { // 帶資源擴展名 → 找真實文件 return locations.stream() .map(loc - createRelative(loc, requestPath)) .filter(resource - resource ! null resource.exists()) .findFirst() .orElseGet(null); } return index; // 其他一切 → index.html }就這么簡單得益于這個解析器用戶在/private刷新時服務(wù)器返回index.html200 OKReact 加載后讀取瀏覽器地址欄 URLReact Router 匹配到private路由并渲染私有頁完美閉環(huán) ? 快速上手一鍵運行 boot-react想親手體驗三步搞定1?? 克隆倉庫git clone https://gitcode.com/gh_mirrors/bo/boot-react cd boot-react2?? 安裝前端依賴需要 Node 6.0 和 yarncd frontend yarn3?? 啟動應(yīng)用./gradlew bootRun啟動后端時前端熱重載開發(fā)服務(wù)器會自動拉起訪問http://localhost:3000即可看到示例應(yīng)用。生產(chǎn)模式打包部署則執(zhí)行./gradlew clean assemble java -jar backend/build/libs/boot-react-0.0.1-SNAPSHOT.jar此時刷新/private不再 404正是SinglePageAppConfig在背后默默工作。 關(guān)鍵文件速查表文件作用backend/src/main/java/react/config/SinglePageAppConfig.java? 生產(chǎn)環(huán)境 pushState 資源解析器本文主角frontend/server.js開發(fā)服務(wù)器含 history 回退與 API 代理frontend/src/router/router.jsReact Router 路由表定義frontend/src/router/privateRoute.js受保護路由未登錄自動跳轉(zhuǎn)登錄頁frontend/assets/index-template.htmlSPA 掛載入口div idrootfrontend/webpack.dev.config.js開發(fā)環(huán)境構(gòu)建與熱重載配置backend/src/main/java/react/config/SecurityConfiguration.javaSpring Security 安全配置README.adoc項目完整使用文檔 總結(jié)boot-react 用不到百行的SinglePageAppConfig給出了 SPA 刷新 404 問題的教科書式解法?白名單區(qū)分靜態(tài)資源與路由請求互不干擾?兜底返回 index.html讓前端路由完全接管? 開發(fā)/生產(chǎn)雙環(huán)境方案開箱即用無論是學習 Spring Boot 集成 React還是尋找一個干凈、完整、帶熱重載和測試的 SPA 起步模板boot-react 都值得納入你的工具箱?!久赓M下載鏈接】boot-reactA starter application with spring boot and react項目地址: https://gitcode.com/gh_mirrors/bo/boot-react創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考