RedwoodJS SSR模式下直接访问绝对URL路由报404如何解决
RedwoodJS 直接访问子路由返回404的配置方案
问题本质
RedwoodJS 是单页应用(SPA),框架内置的navigate方法跳转是纯客户端路由逻辑,不会向服务端发起新的页面请求;但直接在地址栏输入子路由地址时,请求会先打到服务端,服务端找不到对应路径的静态文件就会返回404,需要配置服务端将所有页面请求统一转发到入口index.html,再交给前端路由匹配渲染。
开发环境配置
默认执行yarn rw dev启动的官方开发服务器已经内置了路由fallback逻辑,如果出现404按以下步骤排查修复:
- 先检查
web/src/Routes.js/Routes.tsx的路由定义:确认所有路由都包裹在根<Router>组件内,路径没有拼写错误,且配置了兜底的notfound路由,参考正确写法:import { Router, Route } from '@redwoodjs/router' import HomePage from 'src/pages/HomePage' import SignInPage from 'src/pages/SignInPage' import RegisterPage from 'src/pages/RegisterPage' import NotFoundPage from 'src/pages/NotFoundPage' const Routes = () => { return ( <Router> <Route path="/" page={HomePage} name="home" /> <Route path="/sign-in" page={SignInPage} name="signIn" /> <Route path="/register" page={RegisterPage} name="register" /> <Route notfound page={NotFoundPage} /> </Router> ) } export default Routes - 路由配置无误的话,删除项目根目录的
.redwood缓存文件夹、node_modules/.cache缓存目录,重新执行yarn rw dev启动即可。 - 如果你自定义过web侧的dev server配置(修改过
web/server.config.js),需要手动引入history fallback中间件:- 安装依赖:
yarn workspace web add connect-history-api-fallback -D - 在配置文件中添加中间件,注意要放在静态资源处理逻辑之前:
// web/server.config.js const historyFallback = require('connect-history-api-fallback') module.exports = (config) => { const originalBefore = config.devServer.before config.devServer.before = (app, server) => { app.use(historyFallback()) originalBefore?.(app, server) } return config }
- 安装依赖:
生产环境配置
生产环境需要根据你选择的部署方式,配置对应的路由重写规则,核心逻辑是:所有非静态资源、非/api前缀的请求,全部重写到/index.html,/api前缀的请求正常转发到后端函数服务。
常见部署场景的配置参考:
- 用
yarn rw serve原生启动生产服务:框架默认已经内置了fallback逻辑,不需要额外配置,直接启动即可。 - Nginx反向代理部署:在server配置块中添加如下规则:
# 前端路由fallback location / { root /path/to/your/web/dist; # 替换为web侧构建产物的实际路径 try_files $uri $uri/ /index.html; } # API接口反向代理,不要重写 location /api { proxy_pass http://127.0.0.1:8911; # 替换为你的api侧服务实际监听地址 proxy_set_header Host $host; } - Netlify托管:将重写规则写入
web/public/_redirects文件,构建时会自动发布到产物目录:/api/* /.redwood/functions/:splat 200 /* /index.html 200 - Vercel托管:在项目根目录创建
vercel.json配置重写规则:{ "rewrites": [ { "source": "/api/(.*)", "destination": "/.redwood/functions/$1" }, { "source": "/(.*)", "destination": "/index.html" } ] }
注意:不要把
/api前缀的请求也重写到index.html,否则所有后端接口都会失效。
内容的提问来源于stack exchange,提问作者Daechir
相关产品推荐
相关产品推荐

